PHP HTML代码串 截取实现代码


而且给的数据是HTML代码串,比如这样:

<div class=”aaa”><a href=”/aaa.php?id=1″>张三</a> 评论了 <a href=”/aaa.php?id=444″>李四</a> 分享的 <a href=”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 的结构,会发现它把每个标签都变成了一个对应的对象,里面有相应的属性。举例来说,比如 <a href=”#”>sdf</a> ,这么一条语句对应的一些属性有:

name=>”a”
value => “<a href=”#”>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 属性,不然也不用后台那么辛苦地去截断了。如果大家有更好的方法,欢迎提出!不胜感激。



相关阅读:
Chrome新标签页上神秘的句号
强行卸载Windows Vista SP2的两种方法
xp、2003开3389+非net创建管理用户+Shift后门+自删除脚本vbs
javascript在事件监听方面的兼容性小结
php获取mysql版本的几种方法小结
PHP学习宝典-第六章
如何用javascript判断录入的日期是否合法
Linux防火墙该如何设置
针对class、id所做的CSS HACK
关于Aptana Studio生成自动备份文件的解决办法
ext 同步和异步示例代码
如何在linux下使用u盘
建站选择CMS一定要谨慎
浏览器发展/CSS布局/怎样运用?
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 行草中的对比 国家的形象宣言 创建文明单位讲话稿2篇 高一语文教学计划 最好的思念 一次有趣的口语交际课作文900字 描写人惊恐的句子 那些年我们穿过的校服 夏令营三部曲 关于高三备考的几个关键点 “三下乡社会实践活动”的意义 是福是祸,都得面对;是好是坏,都会过去 爱情里,你最喜欢的他(她),喜欢甚至爱的程度。。。 谢谢你《金色少年 红色之旅》 《床头上的标签》教材分析(会员上传) 小学六年级作文1000字:亲情并非血浓于水———观电影暖春有感 两硬心得体会 作文 夸夸美丽的北江河 工作证明书怎么写 党员个人争先创优活动自查汇报 考《水浒传》作文600字 雪,南方的稀客 教学内容:平移的妙用 —— 初中数学第三册教案 打针 三优一满意活动实施方案 傅雷家书两则教学反思 等待春暖,静候花开 菲星哆拉恋曲(十二)作文1100字 关于前途迷茫的句子 心里空落落的,忍不住来论坛发下怨言 201612月入党思想汇报:吃苦在前,享受在后 衣锦还乡造句 县招商项目工作总结 跟爱情相关的句子:爱情是一个能让人长大的东西。 教学实习鉴定表 装睡的人叫不醒 全面推进新农村建设的思考 新来的数学老师 一念之差作文700字 学骑自行车作文300字 勇敢的精神——《王二小》观后看650字 幼儿园圣诞节目串词 5月酒店工程部工作总结 感恩节敬老院之行活动方案 我的风景700字 送给你的歌 森林公安局长述职述廉工作报告 我和小狗300字 今昔非比 蝶未央 滞留的时光,似水的流年

Copyright © 2016 phpStudy |