2010-08-27 128 views
1

我是新来的模式匹配,终于弄清楚了。我陷入困境,试图找到解决以下问题的方法。模式匹配html标签

我需要返回一个匹配(与PHP preg_match)如果任何一个数字html标签存在。

<p></p> 
<br> 
<h1></h1> 
<h2></h2> 

否则返回不匹配匹配。所以任何没有在上面的列表失败,e.g:

<script></script> 
<table></table> 

ECT

...而且最好我要操作的安全标签,如果可能的白名单。

任何人都知道我可以使用/适应的模式?

回答

2
preg_match_all('/<([a-z]*)\b[^>]*>(.*?)</\1>/i'$html,$matches); 

打破表达

第一/是分隔符

<在标记的开始,第一个<

([a-z]*)开始匹配标签名所以fir实例<

\b[^>]*说,一旦你找到了一个空间,不停地寻找所有单词

>说,它希望在上一节继续找,直到找到第一个>

(.*?)说,不断寻找和收集(..)里面的字符串,但是,我们有一个?,然后停止看,当你发现在大括号后面的下一个字符。

</\1>说我想匹配,但只有当里面的值是一样的第一个比赛,这是由\1在比赛, the value of this would be what's found with做([A-Z] *)`。

那么你可以使用preg_match_all所有与内容找到他们,阵列输出会是这样的

array(
    0 > THE WHOLE TAG 
    1 > TAG NAME 
    2 > TAG VALUE 
) 

希望它能帮助:)

〔实施例

$allowed = array('b','strong','i','pre','code'); WHITELIST, never blacklist 
foreach($matchas as $match) 
{ 
    if(!in_array($match[1],$allowed)) 
    { 
     echo sprintf('The tag %s is disallowed!',$match[1]); 
    } 
} 
+0

因此,这将返回$ html中的所有标签,然后我可以检查不需要的标签? – YsoL8 2010-08-27 10:24:57

+0

是不好更新的例子。 – RobertPitt 2010-08-27 10:40:07

+0

谢谢!看起来很简单。 – YsoL8 2010-08-27 10:45:35

5

即使这不是通常的“I want to parse HTML with regular expressions”的情况,我仍然建议使用DOM解析器,遍历每个元素,如果它不在允许的元素列表中,则放弃。

参见例如this question开始。

这可能它是否支持:not选择器和多标签名称中使用DOM解析器等扩展phpQuery几乎成了一个班轮 - 我不知道,从来没有用它自己的工作,但它会很容易找到出。基本示例是here

2

正则表达式是完全不适合检查HTML的'安全'标签。不仅如此,HTML中也没有安全标签。任何元素都可以被赋予允许脚本注入的属性(例如,onclick,style -with-IE- expression() ...)。您必须检查每个属性以及每个元素。

当您的安全性受到威胁时,您绝对需要一个真正的HTML解析器(然后过滤元素/属性并将结果序列化)。有很多方法可以规避基于正则表达式的检查,但这并不好笑。

您可以使用DOMDocument::loadHTML后跟一个DOM步行来完成此操作,或者您可以使用现有的库,例如htmlpurifier