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中处理模拟rewrite 效果
Dec 09 PHP
兼容性比较好的PHP生成缩略图的代码
Jan 12 PHP
php在多维数组中根据键名快速查询其父键以及父键值的代码
May 07 PHP
7个超级实用的PHP代码片段
Jul 11 PHP
解决File size limit exceeded 错误的方法
Jun 14 PHP
PHP+memcache实现消息队列案例分享
May 21 PHP
php使用cookie保存用户登录的用户名实例
Jan 26 PHP
PHP Oauth授权和本地加密实现方法
Aug 12 PHP
Yii2.0多文件上传实例说明
Jul 24 PHP
PHP实现时间日期友好显示实现代码
Sep 08 PHP
Windows服务器中PHP如何安装redis扩展
Sep 27 PHP
tp5.1 框架数据库高级查询技巧实例总结
May 25 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中的integer类型使用分析
2010/07/27 PHP
PHP函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
2011/07/01 PHP
异步加载技术实现当滚动条到最底部的瀑布流效果
2014/09/16 PHP
php递归调用删除数组空值元素的方法
2015/04/28 PHP
PHP sdk文档处理常用代码示例解析
2020/12/09 PHP
VBScript版代码高亮
2006/06/26 Javascript
在JS数组特定索引处指定位置插入元素的技巧
2014/08/24 Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
2015/09/15 Javascript
基于javascript实现彩票随机数生成(升级版)
2020/04/17 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
jquery遍历标签中自定义的属性方法
2016/09/17 Javascript
使用JS在浏览器中判断当前网络连接状态的几种方法
2017/05/05 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
vue的基本用法与常见指令
2017/08/15 Javascript
nodejs结合Socket.IO实现的即时通讯功能详解
2018/01/12 NodeJs
vue-cli 组件的导入与使用教程详解
2018/04/11 Javascript
vue ssr 实现方式(学习笔记)
2019/01/18 Javascript
vue-cli 项目打包完成后运行文件路径报错问题
2019/07/19 Javascript
浅谈Ant Design Pro 菜单自定义 icon
2020/11/17 Javascript
python实现查找excel里某一列重复数据并且剔除后打印的方法
2015/05/26 Python
Python性能提升之延迟初始化
2016/12/04 Python
Python字符串、整数、和浮点型数相互转换实例
2018/08/04 Python
使用Python实现跳一跳自动跳跃功能
2019/07/10 Python
Python3如何使用多线程升程序运行速度
2020/08/11 Python
来自Ocado的宠物商店:Fetch
2018/07/10 全球购物
xml有哪些解析技术?区别是什么
2016/04/26 面试题
医学生求职自荐信
2013/10/25 职场文书
个人简历中自我评价
2014/02/11 职场文书
新年主持词
2014/03/27 职场文书
家长对孩子的评语
2014/04/18 职场文书
借款协议书范本
2014/04/22 职场文书
领导工作表现评语
2015/01/04 职场文书
远程教育集中轮训基层干部培训班学习心得体会
2016/01/09 职场文书
使用vue-element-admin框架从后端动态获取菜单功能的实现
2021/04/29 Vue.js
解决Python字典查找报Keyerror的问题
2021/05/26 Python
七个非常实用的Python工具包总结
2021/06/15 Python