【问题标题】:Why does this regular expression work?为什么这个正则表达式有效?
【发布时间】:2013-02-14 21:42:34
【问题描述】:

好的,我非常了解为什么这个正则表达式有效。我正在使用的文本是这样的:

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

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

【问题讨论】:

  • 现在是 2013 年。使用 XML 解析器。
  • 哈,那个 html 只是我写的很快,用来测试别人的正则表达式。

标签: regex


【解决方案1】:
/<img(?:(?!alt=).)*?>/

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

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

这个正则表达式,只是在img 之后应用负前瞻。因此,它将匹配所有内容,直到第一个 &gt; 之前的所有 img 标记后面没有 alt=,无论 alt= 是否出现在字符串后面的任何位置。将在.*?中进行介绍

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

这与前一个相同,但它匹配直到最后一个&gt; 的所有内容,因为它使用greedy matching。但我不知道你为什么得到那个输出。在&lt;/html&gt; 的最后一个&gt; 之前,您应该已经得到了一切。


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

【讨论】:

  • 所以你说的是第二个(非贪婪)正则表达式匹配第一个>之前的所有内容,然后验证整个 .* 不是以 alt= 开头。好吧,这一切都说得通。至于贪婪,我将不得不重温这一点,因为它似乎比我记得的要深入得多。谢谢!
  • @Eric。不,它首先验证img 后面没有alt=,然后它只会继续进一步匹配所有内容,直到第一个&gt;
  • 哦,对了,这是有道理的,因为它是向前看而不是向后看。就正则表达式的速度而言,它也更有用。哦,我认为第三个正则表达式一直不匹配到
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
相关资源
最近更新 更多