background image

PHP 的截取 HTML 代码串

需求:将一段文字截取一定的物理长度显示,注意,要截取的不是字符串的字节数
UFT-8 的编码中文字符是 3 个字节或者 4 个字节的,而显示的时候中文会占两个字符的
长度,英文字符只占一个,全角的时候又有不同。而且给的数据是 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>”