PHPHTML代码串截取实现代码
而且给的数据是HTML代码串,比如这样:
<divclass=”aaa”><ahref=”/aaa.php?id=1″>张三</a> 评论了<ahref=”/aaa.php?id=444″>李四</a>分享的<ahref=”bbb.html”>一篇文章文章一长串的东西</a></div>
截取的时候是要截取div标签内部的东西,而且要保留HTML标签,只是对其中的文字做处理。比如我可能只是截取到“李四”的“李”字,但是如果就这样放到前端的话,“李四”前面的a标签是没有闭合的,所以截取之后要保证HTML的语法正确。
这个问题确实不太好搞,让我郁闷了两天。请注意,这只是一个字符串,只不过内容是HTML代码,是没有什么DOM的。如果是在前端处理就好办了,直接DOM获取,然后对里面的节点进行处理,最后把innerHTML之类的东西输出就搞定了。现在可不行了,得换个思路。同事的思路是这样的:
遍历字符串的每一个字符。设置一个标记,碰到标签开始的标记<就置为1,接下来的字符都不记数,然后碰到>之后再开始计数。对标签内部的字符串处理的时候,还要先判断当前字符的编码是不是可能是中文,一般来说PHP中UTF-8编码的中文字符的长度都是3,所以如果碰到是中文字符编码,就要跳过两个不记数……说到这里我自己头已经开始大了。个人认为这种方法很不爽,首先这种精致的逻辑不太容易控制,而且UFT-8编码下中文产生的长度有可能是3个或4个所以代码的严密性值得怀疑。
我个人的思路是,用Tidy来搞(具体用法请看PHP手册吧)。昨天研究了一下那个Tidy,发现这个东西还是挺好用的。首先,把这个字符串转换成Tidy对象,这样:
$tidy=tidy_parse_string($str,array(),‘utf8′); //最后一个是设置编码的,注意,这里是utf8,不是utf-8,没有中间那个连线。
然后获取$tidy中的body(因为转换之后$tidy会自动加上<head><body>等标签):
$body= tidy_get_body($tidy);
这个时候你可以用var_dump看一些$body的结构,会发现它把每个标签都变成了一个对应的对象,里面有相应的属性。举例来说,比如<ahref=”#”>sdf</a>,这么一条语句对应的一些属性有:
name=>”a”
value=>“<ahref=”#”>sdf</a>”
child=>array{[0]=>一个文本节点对象,value是sdf}
attribute=array{”href”=>”#”}
…..其他属性
可以看到,我们其实是可以单独去处理a标签对应节点下面的文字节点的值的,那样就不会破坏任何HTML完整性。原来我以为改变a标签中文字节点的值之后,a标签的value也会跟着改变,那样我直接返回a标签对应节点的value就OK了,没想到不是那个样子,哎,所以处理过其中的文字之后还是要自己拼出新的HTML。
知道了Tidy对象的结构之后,一切就好办了,只要遍历所有的节点,对于本需求来说,就是找到那个div标签,然后开始处理里面的节点。代码如下:
if(mb_strwidth($subchild->value,‘utf-8′)>=$len)
{
$subchild->value=mb_strimwidth($subchild->value,0,$len,‘…",‘utf-8′);
$trimed_str.=$subchild->value;
break;
}
else
{
$trimed_str.=$subchild->value;
$len=$len-mb_strwidth($subchild->value,‘utf-8′);
}
里面的$subchild就是一个子节点。注意,这里使用了mb_strwidth来获取字符串长度。严重推荐一下这个mb_strwidth,很好用,它会把中文当作两个字符长度处理,正好符合这里的需求!而且截取字符串的时候用到了mb_strimwidth,这个函数也会把中文当作两个字符长度处理,mb_开头的函数真是好用啊。
具体代码我就不写出来了,因为是针对一个需求写的,没做成通用的形式。哪天我有时间做成通用的再发布一下。
另外,可惜FireFox不支持text-overflow属性,不然也不用后台那么辛苦地去截断了。如果大家有更好的方法,欢迎提出!不胜感激。
相关文章
- ResNet+FPN实现+白嫖代码「建议收藏」
- 试试使用Spring Event组合@Async注解,轻松实现代码的解耦和异步
- 0行代码拿210万年薪,ChatGPT催生新型「程序员」岗:工作纯靠和AI聊天
- 【Python】这篇罕见的符号编程论文,让你在Jupyter Notebook中手绘草图并变成代码
- 编程神器Copilot逐字抄袭他人代码?GitHub 回应:相似,但不同......
- 【错误记录】PyCharm 中从 GitHub 中 Clone 代码到本地报错 ( OpenSSL SSL_read: Connection was reset, errno 10054 )
- 7个流行的强化学习算法及代码实现
- 用javascript动态注释掉HTML代码
- 一段超强的javascript代码解密方法
- BaiduMusicbox用到的ajax代码
- CSS文字截取功能实现代码
- c#调用.bat文件的实现代码
- javascript大中小字体显示实现代码
- Jquery截取中文字符串的实现代码
- IP地址与整数之间的转换实现代码(asp.net)
- Perl操作系统环境变量的脚本代码
- JavaScript将Table导出到Excel实现思路及代码
- Python字符串操作实现代码(截取/替换/查找/分割)
- 5种PHP创建数组的实例代码分享
- 用box固定长宽实现图片自动轮播js代码
- 使用原生js实现页面蒙灰(mask)效果示例代码
- jQuery截取指定长度字符串的实现原理及代码
- Python实现端口复用实例代码