为什么这个正则表达式有效?

时间:2013-02-14 21:42:35

标签: regex

好的,我完全在为什么这个正则表达式工作。我正在使用的文字是:

<html>
  <body>
    hello
    <img src="withalt" alt="hi"/>asdf
    <img src="noalt" />fdsa<a href="asdf">asdf</a>
    <img src="withalt2" alt="blah" />
  </body>
</html>

使用以下正则表达式(在php中测试但我假设所有perl正则表达式都是如此),它将返回所有不包含alt标记的img标记:

/<img(?:(?!alt=).)*?>/
Returns:
<img src="noalt" />

基于此,我认为简单地删除无后向引用将返回相同的内容:

/<img(?!alt=).*?>/
Returns:
<img src="withalt" alt="hi"/>
<img src="noalt" />
<img src="withalt2" alt="blah" />

如您所见,它只返回所有图像标记。然后让事情变得更加混乱,删除? (据我所知,只是一个通配符)*返回到最后的&gt;

/<img(?!alt=).*>/
Returns:
<img src="withalt" alt="hi"/>
<img src="noalt" />fdsa<a href="asdf">asdf</a>
<img src="withalt2" alt="blah" />

所以任何人都想告诉我,或者至少指出我正确的方向发生在这里?

1 个答案:

答案 0 :(得分:2)

/<img(?:(?!alt=).)*?>/

此正则表达式为img后匹配的每个字符应用否定预测。因此,一旦找到alt=,它就会停止。因此,它只会与img标记匹配,后者没有alt属性。

/<img(?!alt=).*?>/

此正则表达式仅在img之后应用否定预测。因此,无论>是否出现在字符串后面的任何位置,它都将匹配所有img标记的第一个alt=,而不是alt=。它将在.*?

中介绍
/<img(?!alt=).*>/

这与前一个相同,但它匹配最后一个>的所有内容,因为它使用greedy matching。但我不知道你为什么得到那个输出。你应该得到>的最后</html>所有内容。


现在忘记那里发生的一切,然后转向HTML Parser,解析HTML。它们专为此任务而设计。所以,不要费心使用正则表达式,因为你无法通过正则表达式解析各种HTML。