Regex 雷格斯:懒惰更糟糕吗?

Regex 雷格斯:懒惰更糟糕吗?,regex,regex-greedy,non-greedy,reluctant-quantifiers,Regex,Regex Greedy,Non Greedy,Reluctant Quantifiers,我总是这样写正则表达式 <A HREF="([^"]*)" TARGET="_blank">([^<]*)</A> <A HREF="(.*?)" TARGET="_blank">(.*?)</A> 我可以这样写 <A HREF="([^"]*)" TARGET="_blank">([^<]*)</A> <A HREF="(.*?)" TARGET="_blank">(.*?)</A>

我总是这样写正则表达式

<A HREF="([^"]*)" TARGET="_blank">([^<]*)</A>
<A HREF="(.*?)" TARGET="_blank">(.*?)</A>
我可以这样写

<A HREF="([^"]*)" TARGET="_blank">([^<]*)</A>
<A HREF="(.*?)" TARGET="_blank">(.*?)</A>

使用第二种方法有什么缺点吗?正则表达式显然更紧凑(即使如此,解析它也更好)

编辑:这里有两个最佳答案,它们指出了表达式之间的两个重要区别。ysth的回答指出了非贪婪/懒惰的一个弱点,超链接本身可能包含标签的其他属性(肯定不好)。Rob Kennedy指出贪婪示例中的一个弱点,即锚文本不能包含其他标记(肯定不行,因为它也不会捕获所有锚文本)。。。所以答案是,正则表达式就是它们,看起来相同的惰性和非惰性解决方案可能在语义上并不等价


编辑:第三个最好的答案是Alan M关于表达式的相对速度。目前,我将把他的答案列为最佳答案,这样人们会给他更多的分数:)

这里的“懒惰”一词是错误的。你是说不贪婪,而不是贪婪。据我所知,使用它没有缺点。但在你的特殊情况下,它也不应该更有效。

它不是关于好或坏。我见过的术语最多的是贪婪与非贪婪,但不管你怎么说,他们做的是两件不同的事情。您希望为任务使用正确的一个。例如,当您不想在一行中捕获多个匹配项时,请关闭贪婪选项

不贪婪更好,不是吗?它向前工作,每次检查一个匹配项并在找到一个匹配项时停止,而正常的kleene闭包(*)向后工作以匹配其余的输入项并删除内容,直到找到匹配项为止


最后,他们做了不同的事情,但我认为非贪婪者的表现优于贪婪者。请记住,我还没有测试过这一点,但现在我很好奇。

请注意,您的示例并不相同。您的第一个正则表达式不会选择任何包含其他标记的链接,例如
img
b
。第二个正则表达式会,我想这可能是你想要的


除了意义上的差异,我能想到的唯一缺点是,对非贪婪修饰符的支持不像字符类否定那样普遍。如果您正在使用的正则表达式计算器支持它,那么就继续使用它。

补充字符类更严格地定义了您想要匹配的内容,所以只要可以,我都会使用它

非贪婪正则表达式将匹配您可能不想要的内容,例如:

<A HREF="foo" NAME="foo" TARGET="_blank">foo</A>

另一个要考虑的是目标文本的长度,以及它将被量化的子表达式匹配多少。例如,如果您试图匹配大型HTML文档中的整个元素,您可能会尝试使用以下正则表达式:

/<BODY>.*?<\/BODY>/is
/.*?/is
但这会做很多不必要的工作,一次匹配一个字符,同时在每个字符之前进行有效的消极前瞻。您知道标记将非常接近文档的末尾,所以明智的做法是使用普通贪婪量化器;让它将文档的其余部分全部清除,然后回溯匹配结束标记所需的几个字符


在大多数情况下,你不会注意到贪婪量词和不情愿量词之间的速度差异,但这是需要记住的。你应该明智地使用不情愿的量词的主要原因是其他人指出的一个原因:他们可能不情愿地使用量词,但如果这是实现整体匹配所需要的,他们会比你想要的匹配更多。

我不明白你最后的评论。在你看来,这里会匹配什么?为什么会与我们想要的不同?第一个不是吗?在匹配双引号之前匹配尽可能少的字符,因此只匹配foo?ysth:我现在明白你的意思了,即参数被重新排序。很难说在这种情况下我想要匹配什么,因为它不是合法的HTML(或者至少对我来说没有意义)。Kenny:不,*?将首先尝试通过第一个双引号进行匹配,但如果不允许成功匹配,将继续进行第二个双引号,等等。感谢您的回答。这些家伙指的是懒惰或贪婪,我承认这比贪婪和不贪婪更有意义。你可能会感兴趣的是,“那些家伙”实际上是SO成员Jan Goyvaerts是的,我真的不能抱怨SO memeber的质量。我上一次使用这种级别的技术论坛是xSLT论坛,一位著名的大师David Carlie(类似的)亲自回答了大部分问题,Java称之为“不情愿”。量词是贪婪的、占有的或不情愿的。嗨,罗布,这是真的,我确实想要任何可以介于A标签之间的东西。我的正则表达式计算器是否支持它。。。哇,我甚至不知道它不能。我必须检查一下(我在AS3中),然后用它编辑问题。当然,但显然,一旦问题过时了,就没有人再喜欢它了。如果你可以更改已接受的答案,请随意更改。我的回答并没有真正回答这个问题,只是详细阐述了其他答案。我不同意。有三个方面:匹配你不想要的东西,不匹配你想要的东西,以及处理器需要做多少工作。没有人会点击超过一个问题。哦,我应该提到的是,这三个方面比我在发布问题之前知道的要多,所以这是一个很大的帮助,所以感谢你们三位!打赌它取决于实现。谢谢你的回答!