好的,我很清楚为什么这个正则表达式有效。我正在使用的文本是:
<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。