为什么贪心量词比懒惰量词更便宜

时间:2016-03-02 22:17:22

标签: regex

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

enter image description here

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

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

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

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

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

2 个答案:

答案 0 :(得分:9)

贪婪和懒惰的量词在正确应用时同样(昂贵)。然而,懒惰的量词因为它们可以并且通常被用来补偿模式中的不精确而得到了很慢的声誉。

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

当两个表达式都应用于同一输入

<abcdefghijklmnopqrstuvwxyz0123456789>

它们完全匹配相同的文字。不同之处仅在于它们如何到达匹配:“懒惰”表达式尝试越来越长的字符串,在40步(demo 1)之后到达匹配。另一方面,贪婪的表达一直持续到最后,并且仅经过5个步骤(demo 2)后退一次以达到匹配。

请注意,如果您在>

之后添加更多字符,则可以撤消这种情况
<abcdefghijklmnopqrstuvwxyz0123456789>abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789

现在贪婪的表达变成了“慢的”,花了149步(demo 3),而懒惰的表达继续采取与之前相同的40步(demo 4)。

答案 1 :(得分:2)

有时候贪婪很糟糕。

示例[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)是一个开始检查的先行 从下一个角色。这绝对是假的 这会立即设置指向字符串末尾的指针,并开始检查
向后(回溯)。 请注意这一点,因为跳过所有内容 它比看油漆干慢。

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