php对包含html标签的字符串进行截取的函数分享


Posted in PHP onJune 19, 2014

这个方法的作用是:php截取含有html标签的字符串,如果标签未闭合就闭合标签,防止未闭合的标签破坏原网页布局。截取完之后将多余的内容替换为...或者其他任意字符,支持锚点指定替换到指定位置。

/*
* ============================== 截取含有 html标签的字符串 =========================
* @param (string) $str   待截取字符串
* @param (int)  $lenth  截取长度
* @param (string) $repalce 超出的内容用$repalce替换之(该参数可以为带有html标签的字符串)
* @param (string) $anchor 截取锚点,如果截取过程中遇到这个标记锚点就截至该锚点处
* @return (string) $result 返回值
* @demo  $res = cut_html_str($str, 256, '...'); //截取256个长度,其余部分用'...'替换
* -------------------------------------------------------------------------------
* $ Author: Wang Jian.	|	Email: wj@yurendu.com	|	Date: 2014/03/16
* ===============================================================================
*/ 
function cut_html_str($str, $lenth, $replace='', $anchor='<!-- break -->'){ 
	$_lenth = mb_strlen($str, "utf-8");	// 统计字符串长度(中、英文都算一个字符)
	if($_lenth <= $lenth){
		return $str;	// 传入的字符串长度小于截取长度,原样返回
	}
	$strlen_var = strlen($str); 	// 统计字符串长度(UTF8编码下-中文算3个字符,英文算一个字符)
	if(strpos($str, '<') === false){ 
		return mb_substr($str, 0, $lenth);	// 不包含 html 标签 ,直接截取
	} 
	if($e = strpos($str, $anchor)){ 
		return mb_substr($str, 0, $e);	// 包含截断标志,优先
	} 
	$html_tag = 0; 	// html 代码标记 
	$result = ''; 	// 摘要字符串
	$html_array = array('left' => array(), 'right' => array()); //记录截取后字符串内出现的 html 标签,开始=>left,结束=>right
	/*
	* 如字符串为:<h3><p><b>a</b></h3>,假设p未闭合,数组则为:array('left'=>array('h3','p','b'), 'right'=>'b','h3');
	* 仅补全 html 标签,<? <% 等其它语言标记,会产生不可预知结果
	*/ 
	for($i = 0; $i < $strlen_var; ++$i) { 
		if(!$lenth) break;	// 遍历完之后跳出
		$current_var = substr($str, $i, 1); // 当前字符
		if($current_var == '<'){ // html 代码开始 
			$html_tag = 1; 
			$html_array_str = ''; 
		}else if($html_tag == 1){ // 一段 html 代码结束 
			if($current_var == '>'){ 
				$html_array_str = trim($html_array_str); //去除首尾空格,如 <br / > < img src="" / > 等可能出现首尾空格
				if(substr($html_array_str, -1) != '/'){ //判断最后一个字符是否为 /,若是,则标签已闭合,不记录
					// 判断第一个字符是否 /,若是,则放在 right 单元 
					$f = substr($html_array_str, 0, 1); 
					if($f == '/'){ 
						$html_array['right'][] = str_replace('/', '', $html_array_str); // 去掉 '/' 
					}else if($f != '?'){ // 若是?,则为 PHP 代码,跳过
						// 若有半角空格,以空格分割,第一个单元为 html 标签。如:<h2 class="a"> <p class="a"> 
						if(strpos($html_array_str, ' ') !== false){ 
						// 分割成2个单元,可能有多个空格,如:<h2 class="" id=""> 
						$html_array['left'][] = strtolower(current(explode(' ', $html_array_str, 2))); 
						}else{ 
						//若没有空格,整个字符串为 html 标签,如:<b> <p> 等,统一转换为小写
						$html_array['left'][] = strtolower($html_array_str); 
						} 
					} 
				} 
				$html_array_str = ''; // 字符串重置
				$html_tag = 0; 
			}else{ 
				$html_array_str .= $current_var; //将< >之间的字符组成一个字符串,用于提取 html 标签
			} 
		}else{ 
			--$lenth; // 非 html 代码才记数
		} 
		$ord_var_c = ord($str{$i}); 
		switch (true) { 
			case (($ord_var_c & 0xE0) == 0xC0): // 2 字节 
				$result .= substr($str, $i, 2); 
				$i += 1; break; 
			case (($ord_var_c & 0xF0) == 0xE0): // 3 字节
				$result .= substr($str, $i, 3); 
				$i += 2; break; 
			case (($ord_var_c & 0xF8) == 0xF0): // 4 字节
				$result .= substr($str, $i, 4); 
				$i += 3; break; 
			case (($ord_var_c & 0xFC) == 0xF8): // 5 字节 
				$result .= substr($str, $i, 5); 
				$i += 4; break; 
			case (($ord_var_c & 0xFE) == 0xFC): // 6 字节
				$result .= substr($str, $i, 6); 
				$i += 5; break; 
			default: // 1 字节 
				$result .= $current_var; 
		} 
	} 
	if($html_array['left']){ //比对左右 html 标签,不足则补全
		$html_array['left'] = array_reverse($html_array['left']); //翻转left数组,补充的顺序应与 html 出现的顺序相反
		foreach($html_array['left'] as $index => $tag){ 
			$key = array_search($tag, $html_array['right']); // 判断该标签是否出现在 right 中
			if($key !== false){ // 出现,从 right 中删除该单元
				unset($html_array['right'][$key]); 
			}else{ // 没有出现,需要补全 
				$result .= '</'.$tag.'>'; 
			} 
		} 
	} 
	return $result.$replace; 
}
PHP 相关文章推荐
一步一步学习PHP(7) php 字符串相关应用
Mar 05 PHP
PHP的password_hash()使用实例
Mar 17 PHP
php实现ip白名单黑名单功能
Mar 12 PHP
PHP生成唯一订单号的方法汇总
Apr 16 PHP
PHP的伪随机数与真随机数详解
May 27 PHP
Symfony2函数用法实例分析
Mar 18 PHP
php 遍历目录,生成目录下每个文件的md5值并写入到结果文件中
Dec 12 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
Dec 21 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
Apr 02 PHP
laravel执行php artisan migrate报错的解决方法
Oct 09 PHP
laravel 实现向公共模板中传值 (view composer)
Oct 22 PHP
PHP接入微信H5支付的方法示例
Oct 28 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
Jun 19 #PHP
PHP base64编码后解码乱码的解决办法
Jun 19 #PHP
PHP安全的URL字符串base64编码和解码
Jun 19 #PHP
PHP中的多行字符串传递给JavaScript的两种方法
Jun 19 #PHP
ThinkPHP模板引擎之导入资源文件方法详解
Jun 18 #PHP
ThinkPHP CURD方法之field方法详解
Jun 18 #PHP
ThinkPHP CURD方法之data方法详解
Jun 18 #PHP
You might like
LAMP环境使用Composer安装Laravel的方法
2017/03/25 PHP
提交按钮的name='submit'引起的js失效问题及原因
2015/02/25 Javascript
jQuery实现跨域iframe接口方法调用
2015/03/14 Javascript
简单讲解AngularJS的Routing路由的定义与使用
2016/03/05 Javascript
jQuery配合coin-slider插件制作幻灯片效果的流程解析
2016/05/13 Javascript
基于JS实现省市联动效果代码分享
2016/06/06 Javascript
结合代码图文讲解JavaScript中的作用域与作用域链
2016/07/05 Javascript
深入浅出讲解ES6的解构
2016/08/03 Javascript
BootStrap table表格插件自适应固定表头(超好用)
2016/08/24 Javascript
基于JavaScript实现移动端无限加载分页
2017/03/27 Javascript
JS将unicode码转中文方法
2017/05/08 Javascript
Angularjs 实现动态添加控件功能
2017/05/25 Javascript
Angular4学习笔记之新建项目的方法
2017/07/18 Javascript
jQuery中元素选择器(element)简单用法示例
2018/05/14 jQuery
ES6 fetch函数与后台交互实现
2018/11/14 Javascript
vue-cli3.0如何使用CDN区分开发、生产、预发布环境
2018/11/22 Javascript
Vue 表情包输入组件的实现代码
2019/01/21 Javascript
vue实现一拉到底的滑动验证
2019/07/25 Javascript
基于ssm框架实现layui分页效果
2019/07/27 Javascript
vuejs element table 表格添加行,修改,单独删除行,批量删除行操作
2020/07/18 Javascript
Python使用剪切板的方法
2017/06/06 Python
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
python操作xlsx文件的包openpyxl实例
2018/05/03 Python
python使用udp实现聊天器功能
2018/12/10 Python
python-视频分帧&amp;多帧合成视频实例
2019/12/10 Python
英国高级百货公司:Harvey Nichols
2017/01/29 全球购物
高性能装备提升营地:Kammok
2019/02/27 全球购物
Nike墨西哥官网:Nike MX
2020/08/30 全球购物
市场安全管理制度
2014/01/26 职场文书
函授药学自我鉴定
2014/02/07 职场文书
冬季施工防火方案
2014/05/17 职场文书
贯彻落实“八项规定”思想汇报
2014/09/13 职场文书
银行委托书范本
2014/09/28 职场文书
起诉状范本
2015/05/20 职场文书
员工担保书范本
2015/09/22 职场文书
Python实战之实现康威生命游戏
2021/04/26 Python