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



好的,我很清楚为什么这个正则表达式有效。我正在使用的文本是:

<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" />

正如您所看到的,它只是返回所有的图像标记。然后让事情变得更加混乱,删除?(据我所知,这只是一个通配符)在*返回到最终>之后

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

所以有人愿意告诉我,或者至少为我指明这里发生的事情的正确方向吗?

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

此正则表达式对img之后匹配的每个字符应用负向前看。因此,一旦它找到alt=,它就会停止。因此,它将只匹配没有alt属性的img标记。

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

此正则表达式仅在img之后应用负向前看。因此,无论alt=是否出现在字符串后面的任何位置,它都将匹配所有内容,直到没有跟在alt=后面的所有img标签的第一个>。它将包含在.*?

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

这与上一个相同,但它匹配直到最后一个>的所有内容,因为它使用greedy matching。但我不知道你为什么会得到这样的结果。你应该在</html>的最后一个>之前得到所有东西。


现在,忘记那里发生的一切,转向HTML Parser,用于解析HTML。它们是专门为这项任务设计的。所以,不要麻烦使用regex,因为您不能通过regex解析每种HTML。

最新更新