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连mysql和oracle数据库性能比较
Oct 09 PHP
通过table标签,PHP输出EXCEL的实现方法
Jul 24 PHP
PHP如何通过AJAX方式实现登录功能
Nov 23 PHP
thinkphp3.2点击刷新生成验证码
Feb 16 PHP
分享PHP-pcntl 实现多进程代码
Sep 30 PHP
PHP实现小偷程序实例
Oct 31 PHP
php解析mht文件转换成html的实例
Mar 13 PHP
ThinkPHP框架分布式数据库连接方法详解
Mar 14 PHP
laravel 创建命令行命令的图文教程
Oct 23 PHP
laravel框架中间件简单使用方法示例
Jan 25 PHP
通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法
Apr 02 PHP
PhpStorm连接服务器并实现自动上传功能
Dec 09 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
第六章 php目录与文件操作
2011/12/30 PHP
php 定义404页面的实现代码
2012/11/19 PHP
解析php中heredoc的使用方法
2013/06/17 PHP
PHP实现的数组和XML文件相互转换功能示例
2018/03/15 PHP
javascript 类方法定义还是有点区别
2009/04/15 Javascript
DIY jquery plugin - tabs标签切换实现代码
2010/12/11 Javascript
jQuery Trim去除字符串首尾空字符的实现方法说明
2014/02/11 Javascript
封装了一个支持匿名函数的Javascript事件监听器
2014/06/05 Javascript
JQuery实现可直接编辑的表格
2015/04/16 Javascript
window.location.hash知识汇总
2015/11/09 Javascript
Node.js中常规的文件操作总结
2016/10/13 Javascript
Angular和百度地图的结合实例代码
2016/10/19 Javascript
JS中检测数据类型的几种方式及优缺点小结
2016/12/12 Javascript
ES6学习笔记之正则表达式和字符串正则方法分析
2017/04/25 Javascript
利用vscode调试编译后的js代码详解
2018/05/14 Javascript
如何解决webpack-dev-server代理常切换问题
2019/01/09 Javascript
js实现删除li标签一行内容
2019/04/16 Javascript
layui-table获得当前行的上/下一行数据的例子
2019/09/24 Javascript
简单了解JavaScript sort方法
2019/11/25 Javascript
JavaScript oncopy事件用法实例解析
2020/05/13 Javascript
python使用内存zipfile对象在内存中打包文件示例
2014/04/30 Python
完美解决python中ndarray 默认用科学计数法显示的问题
2018/07/14 Python
Python求一批字符串的最长公共前缀算法示例
2019/03/02 Python
Python 3.8中实现functools.cached_property功能
2019/05/29 Python
python manage.py runserver流程解析
2019/11/08 Python
在pycharm中关掉ipython console/PyDev操作
2020/06/09 Python
德国低价购买灯具和家具网站:Style-home.de
2016/11/25 全球购物
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
工程造价专业大学生自荐信
2013/10/01 职场文书
《老王》教学反思
2014/02/23 职场文书
读书活动总结
2014/04/28 职场文书
电子商务专业应届毕业生求职信
2014/06/21 职场文书
党员教师自我剖析材料
2014/09/29 职场文书
个人剖析材料范文
2014/09/30 职场文书
庭外和解协议书
2016/03/23 职场文书
tomcat默认最大连接数及相关调整方法
2022/05/06 Servers