惰性和贪婪在正则expression式中是什么意思?
有人能用一种可以理解的方式解释这两个术语吗?
贪婪会尽可能消耗。 从http://www.regular-expressions.info/repeat.html我们看到了试图用;<.+>
匹配HTML标签的例子。 假设你有以下几点:
<em>Hello World</em>
你可能会认为<.+>
( .
表示任何非换行符 , +
表示一个或多个 )只会匹配<em>
和</em>
,实际上它会非常贪婪,从第一个<
到最后>
。 这意味着它将匹配<em>Hello World</em>
而不是你想要的。
让它懒( <.+?>
)将阻止这一点。 通过添加?
在+
,我们告诉它重复尽可能less的次数 ,所以第一次出现,就是我们想要停止匹配的地方。
我鼓励你下载RegExr ,这是一个很好的工具,可以帮助你探索正则expression式 – 我一直都在使用它。
贪婪的手段匹配最长的string。
懒惰意味着匹配尽可能短的string。
例如,贪婪的h.+l
匹配'hell'
'hello'
中的'hell'
,但懒惰的h.+?l
匹配'hel'
。
贪婪意味着你的expression将尽可能地匹配一个组,懒惰意味着它将匹配尽可能最小的组。 对于这个string:
abcdefghijklmc
和这个expression式:
a.*c
一个贪婪的匹配将匹配整个string,而一个懒惰的匹配只会匹配第一个abc
。
+-------------------+-----------------+------------------------------+ | Greedy quantifier | Lazy quantifier | Description | +-------------------+-----------------+------------------------------+ | * | *? | Star Quantifier: 0 or more | | + | +? | Plus Quantifier: 1 or more | | ? | ?? | Optional Quantifier: 0 or 1 | | {n} | {n}? | Quantifier: exactly n | | {n,} | {n,}? | Quantifier: n or more | | {n,m} | {n,m}? | Quantifier: between n and m | +-------------------+-----------------+------------------------------+
添加一个? 给一个量词来使其不懂得,即懒惰。
例:
testingstring: stackoverflow
贪婪regexpression式 : s.*o
输出: stackoverflo w
懒expression式 : s.*?o
输出: stacko verflow
采取从www.regular-expressions.info
贪婪 :贪婪的量词首先尽可能多地重复该标记,并逐渐放弃与引擎回溯匹配以find总体匹配。
懒惰 :懒惰的量词首先按照需要重复记号,然后通过正则expression式逐渐扩大匹配,find整体匹配。
从正则expression式
正则expression式中的标准量词是贪婪的,这意味着它们尽可能地匹配,只有在必要时才会返回匹配正则expression式的其余部分。
通过使用惰性量词,expression式首先尝试最小匹配。
据我所知,默认情况下,大多数正则expression式引擎是贪婪的。 在量词的末尾添加一个问号将启用懒惰匹配。
正如@Andre S在评论中提到的那样。
- 贪婪:继续search直到条件不满足。
- 懒惰:一旦条件满足就停止search。
请参考下面的例子,了解什么是贪婪的,什么是懒惰的。
import java.util.regex.Matcher; import java.util.regex.Pattern; public class Test { public static void main(String args[]){ String money = "100000000999"; String greedyRegex = "100(0*)"; Pattern pattern = Pattern.compile(greedyRegex); Matcher matcher = pattern.matcher(money); while(matcher.find()){ System.out.println("I'm greeedy and I want " + matcher.group() + " dollars. This is the most I can get."); } String lazyRegex = "100(0*?)"; pattern = Pattern.compile(lazyRegex); matcher = pattern.matcher(money); while(matcher.find()){ System.out.println("I'm too lazy to get so much money, only " + matcher.group() + " dollars is enough for me"); } } }
结果是:
我好羡慕,我想要1亿美元。 这是我能得到的最多。
我懒得拿这么多钱,只有100美元就够了
尝试了解以下行为:
var input = "0014.2"; Regex r1 = new Regex("\\d+.{0,1}\\d+"); Regex r2 = new Regex("\\d*.{0,1}\\d*"); Console.WriteLine(r1.Match(input).Value); // "0014.2" Console.WriteLine(r2.Match(input).Value); // "0014.2" input = " 0014.2"; Console.WriteLine(r1.Match(input).Value); // "0014.2" Console.WriteLine(r2.Match(input).Value); // " 0014" input = " 0014.2"; Console.WriteLine(r1.Match(input).Value); // "0014.2" Console.WriteLine(r2.Match(input).Value); // ""