PHP HTML代码串 截取实现代码


Posted in PHP onJune 29, 2009

而且给的数据是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 属性,不然也不用后台那么辛苦地去截断了。如果大家有更好的方法,欢迎提出!不胜感激。

PHP 相关文章推荐
剖析 PHP 中的输出缓冲
Dec 21 PHP
MySQL数据库转移,access,sql server 转 MySQL 的图文教程
Sep 02 PHP
表单复选框向PHP传输数据的代码
Nov 13 PHP
PHP $_SERVER详解
Jan 16 PHP
PHP中几种常见的超时处理全面总结
Sep 11 PHP
file_get_contents获取不到网页内容的解决方法
Mar 07 PHP
从零开始学YII2框架(一)通过Composer安装Yii2框架
Aug 20 PHP
php+mysql大量用户登录解决方案分析
Dec 29 PHP
php+curl 发送图片处理代码分享
Jul 09 PHP
php实现curl模拟ftp上传的方法
Jul 29 PHP
php简单解析mysqli查询结果的方法(2种方法)
Jun 29 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
PHP 网页过期时间的控制代码
Jun 29 #PHP
PHP 超链接 抓取实现代码
Jun 29 #PHP
PHP 文件上传功能实现代码
Jun 24 #PHP
php addslashes 函数详细分析说明
Jun 23 #PHP
PHP n个不重复的随机数生成代码
Jun 23 #PHP
PHP 七大优势分析
Jun 23 #PHP
php 404错误页面实现代码
Jun 22 #PHP
You might like
PHP 中文处理技巧
2010/04/25 PHP
php源码加密 仿微盾PHP加密专家(PHPCodeLock)
2010/05/06 PHP
深入探讨PHP中的内存管理问题
2011/08/31 PHP
php xml常用函数的集合(比较详细)
2013/06/06 PHP
destoon各类调用汇总
2014/06/20 PHP
php实现在服务器端调整图片大小的方法
2015/06/16 PHP
laravel实现批量更新多条记录的方法示例
2017/10/22 PHP
有关PHP 中 config.m4 的探索
2020/08/26 PHP
jQuery 改变CSS样式基础代码
2010/02/11 Javascript
Javascript 面向对象 命名空间
2010/05/13 Javascript
JS实现仿中关村论坛评分后弹出提示效果的方法
2015/02/23 Javascript
jQuery实现带动画效果的二级下拉导航方法
2015/03/11 Javascript
js调用屏幕宽度的简单方法
2016/11/14 Javascript
详解nodejs微信公众号开发——4.自动回复各种消息
2017/04/11 NodeJs
jQuery实现碰到边缘反弹的动画效果
2018/02/24 jQuery
vue-quill-editor富文本编辑器简单使用方法
2018/09/21 Javascript
小程序云开发部署攻略(图文教程)
2018/10/30 Javascript
基于vue和bootstrap实现简单留言板功能
2020/05/30 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
vue实现简易的双向数据绑定
2020/12/29 Vue.js
[01:04:01]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第一场
2014/05/24 DOTA
python连接mysql并提交mysql事务示例
2014/03/05 Python
详解在Python程序中解析并修改XML内容的方法
2015/11/16 Python
Pandas:DataFrame对象的基础操作方法
2018/06/07 Python
通过python顺序修改文件名字的方法
2018/07/11 Python
python 为什么说eval要慎用
2019/03/26 Python
Python 迭代,for...in遍历,迭代原理与应用示例
2019/10/12 Python
Python Pandas 转换unix时间戳方式
2019/12/07 Python
python 实现将小图片放到另一个较大的白色或黑色背景图片中
2019/12/12 Python
pandas DataFrame 数据选取,修改,切片的实现
2020/04/24 Python
Python 私有属性和私有方法应用场景分析
2020/06/19 Python
施华洛世奇美国官网:SWAROVSKI美国
2018/02/08 全球购物
类的核心特性有哪些
2014/01/01 面试题
JPA的优势都有哪些
2013/07/04 面试题
会计主管岗位职责
2014/01/03 职场文书
小学少先队活动方案
2014/02/18 职场文书