`Greedy`和`Reluctant`正则表达式量词有什么区别?
来自Pattern
javadocs:
贪心量词: X? X,曾经或根本没有 X * X,零次或多次 X + X,一次或多次 X {n} X,正好是n次 X {n,} X,至少n次 X {n,m} X,至少n但不超过m倍 不情愿的量词: X?? X,曾经或根本没有 X*? X,零次或多次 X +? X,一次或多次 X {N}? X,正好是n次 X {N,}? X,至少n次 X {N,M}? X,至少n但不超过m次
他们所做的事情的描述是一样的…那么,有什么区别?
我真的很感激一些例子。
我使用Java编写代码,但我听说这个概念对于大多数现代正则表达式实现都是一样的。
一个贪婪的运算符总是试图“抓取”尽可能多的输入,而一个不情愿的量词将尽可能少地匹配输入并仍然创建一个匹配。
例:
"The red fox jumped over the red fence" /(.*)red/ => \1 = "The red fox jumped over the " /(.*?)red/ => \1 = "The " "aaa" /a?a*/ => \1 = "a", \2 = "aa" /a??a*/ => \1 = "", \2 = "aaa" "Mr. Doe, John" /^(?:Mrs?.)?.*\b(.*)$/ => \1 = "John" /^(?:Mrs?.)?.*?\b(.*)$/ => \1 = "Doe, John"
在此链接中 ,教程作者承认您的问题的精神:
乍一看,似乎量词X?,X ?? 和X?+完全相同,因为它们都承诺匹配“X,一次或根本不匹配”。 有一些细微的实现差异,将在本节末尾附近解释。
他们继续汇总实例并提供解释:
贪心量词被认为是“贪婪的”,因为它们在尝试第一次匹配之前强制匹配器读入或吃掉整个输入字符串。 如果第一次匹配尝试(整个输入字符串)失败,匹配器将输入字符串后退一个字符并再次尝试,重复该过程直到找到匹配项或者没有剩余字符可以退出。 根据表达式中使用的量词,它将尝试匹配的最后一件事是1或0个字符。
然而,不情愿的量词采用相反的方法:它们从输入字符串的开头开始,然后不情愿地一次吃一个字符寻找匹配。 他们尝试的最后一件事是整个输入字符串。
对于额外的功劳,所有权的解释:
最后,占有量词总是占用整个输入字符串,尝试一次(并且只有一次)匹配。 与贪婪的量词不同,占有量词永远不会退缩,即使这样做也会使整体匹配成功。
一个贪婪的量词将尽可能匹配并仍然得到匹配一个不情愿的量词将匹配可能的最小量。
例如给定字符串
ABCDEF
贪婪的资格赛
ab [az] * [az]将匹配abcdef
不情愿的资格赛
ab [az] *?[az]将匹配abc
假设你有一个正则表达式"a\w*b"
,并在"abab"
上使用它贪婪匹配将匹配"abab"
(它寻找一个a
,尽可能多地出现\w
和b
)和不情愿的匹配将只匹配"ab"
(尽可能小) \w
有关于Perl如何处理这些量词perldoc perlre
。
默认情况下,量化的子模式是“贪婪的”,也就是说,它将尽可能多地匹配(给定一个特定的起始位置),同时仍然允许模式的其余部分匹配。 如果您希望它与可能的最小次数匹配,请使用“
?
”跟随量词。 请注意,含义不会改变,只是“贪婪”:*? 匹配0次或更多次,而不是贪婪 +? 匹配1次或更多次,而不是贪婪 ?? 匹配0或1次,而不是贪婪 {N}? 恰好匹配n次,而不是贪婪 {N,}? 匹配至少n次,而不是贪婪 {N,M}? 匹配至少n但不超过m次,而不是贪婪默认情况下,当量化的子模式不允许整个模式的其余部分匹配时,Perl将回溯。 但是,这种行为有时是不可取的。 因此,Perl也提供了“占有”量词forms。
* +匹配0次或更多次并且不提供任何回报 ++匹配1次或更多次,不给任何回报 ?+匹配0或1次,什么都不给 {n} +完全匹配n次并且不返回任何内容(冗余) {n,} +匹配至少n次并且不给任何回报 {n,m} +匹配至少n但不超过m次并且不返回任何内容例如,
'aaaa'=〜/ a ++ a /永远不会匹配,因为
a++
将吞噬字符串中的所有a
,并且不会留下任何模式的剩余部分。 此function对于提供有关不应回溯的位置的perl提示非常有用。 例如,当写为:时,可以最有效地执行典型的“匹配双引号字符串”问题:/"(?:[^"\\]++|\\.)*+"/我们知道,如果最终报价不匹配,回溯将无济于事。 有关更多详细信息,请参见独立子表达式
(?>...)
; 占有量词只是该构造的语法糖。 例如,上面的例子也可以写成如下:/"(?>(?:(?>[^"\\]+)|\\.)*)"/