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 sprintf()函数让你的sql操作更安全
Jul 23 PHP
php遍历目录viewDir函数
Dec 15 PHP
PHP array_flip() 删除重复数组元素专用函数
May 16 PHP
PHP常用开发函数解析之数组篇[未完结]
Jul 30 PHP
PHP实现删除非站内外部链接实例代码
Jun 17 PHP
PHP+Memcache实现wordpress访问总数统计(非插件)
Jul 04 PHP
php生成静态html页面的方法(2种方法)
Sep 14 PHP
PHP实现微信网页授权开发教程
Jan 19 PHP
浅析PHP7新功能及语法变化总结
Jun 17 PHP
PHP排序算法之归并排序(Merging Sort)实例详解
Apr 21 PHP
Laravel框架实现利用中间件进行操作日志记录功能
Jun 06 PHP
php 中htmlentities导致中文无法查询问题
Sep 10 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
apache+mysql+php+ssl服务器之完全安装攻略
2006/09/05 PHP
PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题
2016/08/12 PHP
关于php中的json_encode()和json_decode()函数的一些说明
2016/11/20 PHP
PHP实现合并两个排序链表的方法
2018/01/19 PHP
Smarty模板配置实例简析
2019/07/20 PHP
javascript开发技术大全 第4章 直接量与字符集
2011/07/03 Javascript
判断JS对象是否拥有某种属性的两种方式
2013/12/02 Javascript
JavaScript中的数值范围介绍
2014/12/29 Javascript
理解Javascript的动态语言特性
2015/06/17 Javascript
详解js的事件处理函数和动态创建html标记方法
2016/12/16 Javascript
canvas雪花效果核心代码分享
2017/02/19 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
Vue filters过滤器的使用方法
2017/07/14 Javascript
在vue项目中安装使用Mint-UI的方法
2017/12/27 Javascript
Vue2.0+Vux搭建一个完整的移动webApp项目的示例
2019/03/19 Javascript
[01:45:05]VGJ.T vs Newbee Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
使用python装饰器验证配置文件示例
2014/02/24 Python
Python找出文件中使用率最高的汉字实例详解
2015/06/03 Python
Python使用设计模式中的责任链模式与迭代器模式的示例
2016/03/02 Python
Python使用pandas处理CSV文件的实例讲解
2018/06/22 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
Python对象转换为json的方法步骤
2019/04/25 Python
python+jinja2实现接口数据批量生成工具
2019/08/28 Python
Python容器使用的5个技巧和2个误区总结
2019/09/26 Python
Python jieba库用法及实例解析
2019/11/04 Python
Python进程间通信multiprocess代码实例
2020/03/18 Python
Python logging模块异步线程写日志实现过程解析
2020/06/30 Python
使用Python画了一棵圣诞树的实例代码
2020/11/27 Python
用ldap作为django后端用户登录验证的实现
2020/12/07 Python
使用CSS3代码绘制可爱的Hello Kitty猫
2016/08/03 HTML / CSS
CSS中的字体大小设置属性总结
2016/05/24 HTML / CSS
5个HTML5的常用本地存储方式详解与介绍
2021/03/27 HTML / CSS
店面销售职位的职责
2014/03/09 职场文书
检查机关党的群众路线个人整改措施
2014/10/04 职场文书
python opencv将多个图放在一个窗口的实例详解
2022/02/28 Python
Beekeeper Studio开源数据库管理工具比Navicat更炫酷
2022/06/21 数据库