正则表达式非捕获组正在捕获

时间:2011-05-05 15:26:29

标签: html regex anchor

我有这个正则表达式

(?:\<a[^*]href="(http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?)>

此正则表达式的要点是捕获具有以“http://”开头或以“.pdf”结尾的href的锚的每个结束标记('&gt;')。

正则表达式有效,但它正在捕获锚点的第一部分,我绝对不需要捕获它。

在下面的示例中,除了第二个之外都是匹配的(这很好)但是只应捕获最后一个括号,但情况并非如此。

<a href="http://blabla">omg</a>
<a href="blabla">omg</a>
<a href="http://blabla.pdf">omg</a>
<a href="/blabla.pdf">omg</a>

例如:如果我们采取第一场比赛:

<a href="http://blabla">

我只想捕捉最后一个括号(我用括号括起来的那个):

<a href="http://blabla"(>)

那么为什么非捕获组正在捕获?我怎样才能抓住锚的最后一个支架

即使我将我的正则表达式简化为以下内容,它仍然无法正常工作

(?:\<a[^*]href="http://[^"]+"+[^>]*)(>)

谢谢,

5 个答案:

答案 0 :(得分:4)

将您的正则表达式重写为:

(?:\<a[^*]href="(?:http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?)(>)
   non capture __^^                                    ^ ^
                                             capture __|_|

Tony Lukasavage说,有一个不必要的非捕获组,而且,没有必要逃避<,所以它变成:

  <a[^*]href="(?:http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?(>)
non capture __^^                                    ^ ^
                                          capture __|_|

答案 1 :(得分:3)

您将两个截然不同的概念混为一谈:捕获消费。正则表达式通常会消耗它们匹配的任何内容;这才是他们的工作方式。此外,大多数正则表达式风格允许您使用capturing groups来挑选整体匹配的特定部分。 (总体匹配通常被称为第零个捕获组,但这只是一个比喻。)

听起来您正在尝试匹配整个<A>标记,但只使用最终的>。这在大多数正则表达式中是不可能的,包括JavaScript。但是如果您使用的是Perl或PHP,则可以使用\K来欺骗匹配开始位置:

(?i)<a\s+[^>]+?href="http://[^"]+"[^>]*\K>

在.NET中你可以使用lookbehind(就像前瞻,匹配而不消耗):

(?i)"(?<=<a\s+[^>]+?href="http://[^"]+"[^>]*)>

在支持lookbehinds的其他版本中,大多数都会对它们施加限制,导致它们无法用于此任务。

答案 2 :(得分:2)

如果我正确理解你想要匹配结束锚标记的大于号(>),那么应该这样做:

\<a[^*]href="(http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?(>)

答案 3 :(得分:1)

如果我正确理解您的请求......

\<a[^*]href="(?:http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?(>)

答案 4 :(得分:0)

你的括号围绕着标签本身和href的内容,所以这就是要捕获的内容。如果你需要捕获结束&gt;然后将括号括在它周围。