为什么贪婪的量词比懒惰的量词便宜

http://www.rexegg.com/regex-quantifiers.html#tempered_greed

在这里输入图像描述


贪婪量词 (默认) - 在缓慢减少逐个匹配的字符数量之前,通过吞咽尽可能多的字符来工作,以便为该模式的其余部分让路。

例如,对字符串hello world的正则表达式.*world将首先尝试吞下整个字符串并将其放入.* 。 但它不能,因为world不能匹配,所以.*开始放弃字符,直到它放弃了原始字符串中的world - 在这种情况下,整个正则表达式可以匹配。

懒惰的量词 - 以相似的方式工作,除了相反。 他们希望匹配尽可能少的字符,并且他们做同样的事情,逐个添加更多的字符,直到模式的其余部分有匹配的机会


但根据我阅读的这篇文章,这些贪婪懒惰量词的看似相同的过程是不同的 - 因为只有懒惰的量词才有必要“回溯”。 但是不要贪婪的量词在吐出先前被吞噬的元素时也需要“回溯”?

为什么会这样? 它看起来很直观


贪婪和懒惰的量词在正确应用时同样(昂贵)。 然而,懒惰的量词有一个不好的名声,因为它们可以并且经常用于补偿模式中的不精确性。

考虑一个简单的例子: <.*?><.*>

当两个表达式都应用于相同的输入时

<abcdefghijklmnopqrstuvwxyz0123456789>

它们完全匹配相同的文本。 区别仅在于他们如何抵达比赛:“懒惰”表达式尝试越来越长的字符串,经过40步(演示1)后到达比赛。 另一方面,贪婪的表情一路走到最后,并且只经过5个步骤就回退一次(演示2)。

请注意,如果在>后面添加更多字符,则情况可能会颠倒过来:

<abcdefghijklmnopqrstuvwxyz0123456789>abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789

现在贪婪的表情变成了“缓慢的表情”,采取了149个步骤(演示3),而懒惰的表情继续采用与之前相同的40个步骤(演示4)。


有时候贪心很糟糕。

示例[asdfsikbfqew0787072143k*(*&^(**&]

长凳

Regex1:   [[^]]*]
Options:  < none >
Completed iterations:   200  /  200     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    0.48 s,   476.21 ms,   476211 µs


Regex2:   [.*?]
Options:  < none >
Completed iterations:   200  /  200     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    0.32 s,   322.73 ms,   322730 µs

永远,但永远不要贪婪的点,除非它要求在行尾的残余。

有人曾经告诉我,这个(?=.*d)是一个从下一个字符开始检查的前瞻。 这绝对是错误的。
这立即将指针设置为字符串的结尾,并开始检查
向后(回溯)。 小心这个,因为它跳过了一切。
它比观看油漆干燥要慢。

我总是使用贪婪,现在我只是在强迫时才使用它,而且
我不推荐给任何人。

链接地址: http://www.djcxy.com/p/13429.html

上一篇: Why are greedy quantifiers less expensive than lazy quantifiers

下一篇: Does Emacs regex support possessive quantifiers?