最近业余时间在维护一个rss聚合应用,就发现很多网站feed的条目摘要存在各种问题,用strip_tags一刀切吧,对摘要的段落和样式扭曲了

例如:有一些网站的摘要是截断输出,例如指定的摘要长度截断,这样会导致摘要中出现非闭合的html标签,下面的摘要是一个例子:

$str=<<<EOF
<P>  【手机中国 导购】时间过得真快,转眼就我们就已经度过了2013年的上半年,而我们也悄无声息地老了半岁。不过随着时间的流逝,手机行业也在快速的进步着,其发展速度之快可以用日新月异来形容了。</P>
<P align=center><IMG style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-RIGHT: black 1px solid" alt="2.2GHz骁龙800四核 上半年热门机N宗最 " align=1 src="http://imgm.cnmo.com/cnmo_product/18_500x375/698/ceFYnyzZgUijQ.jpg"><BR>2012年的旗舰机型HTC Butterfly</P>
<P>  回首2012年,手机市场还处于一个相对比较矛盾的时期,国产手机的初露锋芒以及国际大牌的推陈出新,让消费者有些摸不清头脑。到了2013年之后,虽然这个现象还存在着,唯一不同的就是消费者已经逐渐习惯了这个现状,整个手机行业也是在不断的向前进。</P>
<P>  毫不夸张的说,今天刚刚上市了一款各个方面都表现突出的机皇级旗舰机,也许明天就被其他品牌旗舰所取代,这是一个不争的事实。但相比来说,每个品牌每款旗舰也都有自己的特长,比如处理器主频高或是屏幕尺寸大等等。</P>
<P align=center><IMG style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-RIGHT: black 1px solid" alt="6.44英寸屏骁龙800 上半年热门机N宗最 " src="http://img.cnmo-img.com.cn/905/904155.jpg"></P>
<P>  俗话说风水轮流转,曾经榜上有名的强机也许今天就名落孙山,物竞天择,适者生存这句话说的不无道理。今天笔者也给大家统计了2013上半年最新智能手机N宗最,下面就让我们一起看一下吧。<STRONG>
EOF;

上面的摘要有几点不合法:

1.html标签大写

2.最后一个strong由于截断没有正常闭合,strong的父标签p丢失

3.标签的属性中出现了一些样式属性和定义,像:align,style

下面说一说它们的影响

2:如果不加处理的输出会造成页面样式混乱,像非正常闭合的strong浏览器会自动把它后面的输出算成它的子元素.

3:样式定义可能影响你的页面样式,图片溢出你的摘要容器

1:不会造成视觉上的错误,但它会影响你的html合法性

下面来说说处理方法

3:可以用正则把属性给替换掉,像

preg_replace("/<([a-z][a-z0-9]*)(?:[^>]*(\ssrc=['\"][^'\"]*['\"]))?[^>]*?(\/?)>/i",'<$1$2$3>',$str);

2:可以用DOMNode::C14N方法来规范,它可以把丢失的标签给补上,只不过<img />会变成<img></img>

等等:
1.为什么不用strip_tags来处理呢?
是可以,虽然它也可以保留指定的标签,但我会把哪些不安全的标签交给htmlentities

2.好像dom可以删除属性吧!
对,这是下面要讲的,综合处理1,2,3的代码如下

$doc = new DOMDocument();
$doc->formatOutput=false; $doc->loadHTML(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8'));
$nodes = $doc->getElementsByTagName('*');
foreach ( $nodes as $node ) {
$delAtts=array();
//找到节点的所有属性
$nodeN=$node->tagName;
$nodeAtts=$node->attributes;
foreach($nodeAtts as $attN=>$att){
//是img保留src属性
if(strtolower($attN)=='src' && strtolower($nodeN)=='img') continue;
//不是直接删除所有属性
array_push($delAtts,$attN);
}
foreach($delAtts as $A){
$node->removeAttribute($A);
}
}
$doc->saveHTML();
$pstr=$doc->GetElementsByTagName('body')->item(0)->C14N();
//clear empty tag
$pstr=preg_replace('/<(\w+)>(\s| )*<\/\1>/i',"",$pstr);

大体上已经OK了,$pstr的内容是body包裹的$str,最后只需要把body解决掉就可以.

最后要说的有几点:

1.一定不要在遍历属性时把它删除,例如:img有三个属性style,src,alt,它只会删除掉style,style后面的并不会删除

2.一定不要用saveHTML()的返回值作为后续处理的内容,后果是汉字变成如下的东东:

  回首2012年,手机市场&#36824

也不要怕,只需要再调一次

mb_convert_encoding($str, 'UTF-8','HTML-ENTITIES')

就ok了,为了偷懒,所以它的返回值不要用

3.$doc->GetElementsByTagName('body')->item(0)->C14N();

也可以换成:

$doc->documentElement->C14N();

只不过返回值不光有body还有html标签,不在乎的话也可以用它,毕竟比GetElementsByTagName更省事

不合规范的html段落php处理细则的更多相关文章

  1. MIPI CSI-2规范一——概述及层级

    MIPI CSI-2规范一——概述及层级 CSI-2概述 CSI-2规范定义了发送者和接收者之间传输和控制接口的标准数据.数据传输接口(指CSI-2)是单向差分串行接口,传输数据和始终信号:接口的物理 ...

  2. 漫谈PHP代码规范

    前言 虽说PHP是世界上最好的语言,但是写出来的PHP代码却往往不是最美观的.究其原因,可能正式因为PHP简单易上手,适合快速迭代的特性,导致了我们沉浸在迅速完成需求迭代的窃喜中,却忘记了规范性.忽略 ...

  3. c++开发规范

    目录 1. 头文件 1.1. Self-contained 头文件 1.2. #define 保护 1.3. 前置声明 1.4. 内联函数 1.5. #include 的路径及顺序 2. 作用域 2. ...

  4. Python代码规范

    一:背景 用于规范化ocp python开发,对于使用python开发的程序使用统一的风格,便于代码的维护 二:python风格规范 分号:不要在行尾加分号,也不要用分号将两条命令放在同一行 括号:宁 ...

  5. How browsers work

    这几天翻译一篇旧文 How browsers work ( 以现代浏览器chrome.火狐.safari 为对象来分析),这篇文章网上有其他的翻译版本,自己再翻译一遍主要是练习阅读英文文章,而且自己翻 ...

  6. 前端学PHP之Smarty模板引擎

    前面的话 对PHP来说,有很多模板引擎可供选择,但Smarty是一个使用PHP编写出来的,是业界最著名.功能最强大的一种PHP模板引擎.Smarty像PHP一样拥有丰富的函数库,从统计字数到自动缩进. ...

  7. PHP之Smarty模板引擎

    前面的话 对PHP来说,有很多模板引擎可供选择,但Smarty是一个使用PHP编写出来的,是业界最著名.功能最强大的一种PHP模板引擎.Smarty像PHP一样拥有丰富的函数库,从统计字数到自动缩进. ...

  8. Java中常用到的文件操作那些事(一)——替换doc文档模板,生成真实合同案例

    工作中,我们时常会遇到一些操作文件的操作,比如在线生成合同模板,上传/下载/解析Excel,doc文档转为pdf等操作.本文就已工作中遇到的在线生成合同为例,简要地介绍一种文档替换写法. 本文目的:给 ...

  9. HUST软测1504班第2周作业成绩:WordCount

    说明 本次公布的成绩为第2周个人作业WordCount的结果: 第2周个人作业:WordCount 如果同学对作业结果存在异议,可以: 在毕博平台讨论区的第2周作业第在线答疑区发帖申诉. 或直接在博客 ...

随机推荐

  1. Windows XP环境下 搭建Android NDK环境

    搭建Android NDK环境 Windows XP环境下 1 一些下载 ① NDK r7:http://developer.android.com/sdk/ndk/index.html ② cygw ...

  2. !!!!!安卓界面总是显示载入进度条的问题,没事别乱用ListFragment

    近期的安卓应用快完工了.可是个别界面有瑕疵,怎么改动都解决不了.挥之不去的阴影.问题例如以下: 在界面上,数据已经载入完成了.可还是有一股圆形的进度条,感觉它老是在载入什么东西,严重影响界面美观: 1 ...

  3. R语言与数据分析之六:时间序列简介

    今年在某服装企业蹲点了4个多月,之间非常长一段时间在探索其现货和期货预測.时间序列也是做销售预測的首选,今天和小伙伴分享下时间序列的基本性质和怎样用R来挖据时间序列的相关属性. 首先读入一个时间序列: ...

  4. java.lang.ClassCastException: sun.proxy.$Proxy11 cannot be cast to分析

    报这个错,只有一个原因,就是你转化的类型不对. 如果你的类是一个单实体类,也就是没有继承或是接口别的类. public class HjmServiceImpl {} 那么这样写就可以: HjmSer ...

  5. IOS上怎样画出1像素的线

    #define SINGLE_LINE_WIDTH (/[UIScreen mainScreen].scale) #define SINGLE_LINE_ADJUST_OFFSET ((/[UIScr ...

  6. ASI简单实现网络编程

    使用iOS SDK中的HTTP网络请求API,相当的复杂,调用比較麻烦.ASIHTTPRequest 对CFNetwork API进行了封装.而且使用起来非常easy的一套API,在非常多比較老旧的项 ...

  7. django中mysql数据库设置错误解决方法

    刚在django中settings.py进行设置mysql数据库. 当进行执行python manage.py shell命令时会报以下错误: 只需要在settings.py中 DATABASES = ...

  8. java中Executor、ExecutorService、ThreadPoolExecutor介绍(转)

    1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /**     * Executes th ...

  9. 基于三星I9250演示自己弄的Miracast功能-手机对手机

    最终把Miracast功能測试通了,为了节省时间.我的Source端和Sink端都採用同一个机型.这样能够降低我为目标机编译4.4.2源码所耗费的时间.今天简单录制了一段视频.视频是用手机录制的,室内 ...

  10. XSS分析及预防(转)

    阅读目录 XSS的种类和特点 XSS预防 总结 XSS(Cross Site Scripting),又称跨站脚本,XSS的重点不在于跨站点,而是在于脚本的执行.在WEB前端应用日益发展的今天,XSS漏 ...