What do 'lazy' and 'greedy' mean in the context of regular expressions?
有人能用一种可以理解的方式解释这两个术语吗?
贪婪的人会尽可能地消费。从http://www.regular-expressions.info/repeat.html我们可以看到尝试将HTML标记与
1 | Hello World |
你可能认为
让它变懒(
我建议您下载regexr,这是一个很好的工具,可以帮助您探索正则表达式——我一直在使用它。
"greedy"表示匹配尽可能长的字符串。
"lazy"表示匹配尽可能短的字符串。
例如,贪婪的
1 2 3 4 5 6 7 8 9 10 | +-------------------+-----------------+------------------------------+ | 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 | +-------------------+-----------------+------------------------------+ |
Add a ? to a quantifier to make it ungreedy i.e lazy.
例子:测试字符串:stackoverflow贪婪注册表表达式:
贪婪意味着你的表达式将尽可能匹配一个大的组,懒惰意味着它将尽可能匹配最小的组。对于此字符串:
1 | abcdefghijklmc |
这个表达式:
1 | a.*c |
贪婪的匹配将匹配整个字符串,而懒惰的匹配将只匹配第一个
据我所知,大多数regex引擎在默认情况下都是贪婪的。在量词末尾添加问号将启用惰性匹配。
正如评论中提到的那样。
- 贪婪:继续搜索直到条件不满足为止。
- 懒惰:条件满足后停止搜索。
请参阅下面的示例,了解什么是贪婪的,什么是懒惰的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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"); } } } |
结果是:
我是格蕾迪,我要100000000美元。这是我能得到的最多的。
我太懒了,拿不到这么多钱,只有100美元就够了
摘自www.regular-expressions.info
贪婪:贪婪的量词首先尝试重复符号多次尽可能,并逐渐放弃匹配作为引擎的回溯来查找整体匹配。
惰性:惰性量词首先根据需要重复标记几次,并且随着引擎在regex中的后退,匹配逐渐扩展到找到一个整体匹配。
从正则表达式
The standard quantifiers in regular
expressions are greedy, meaning they
match as much as they can, only giving
back as necessary to match the
remainder of the regex.By using a lazy quantifier, the
expression tries the minimal match
first.
贪婪意味着它将消耗你的模式,直到没有一个模式被保留下来,并且它不能再看下去。
懒惰会在遇到您请求的第一个模式时立即停止。
我经常遇到的一个常见例子是regex
由于
最佳shown by example。字符串。正则表达式 192.168.1.1和贪婪的B + B"的。你可能会认为这会给你真爱第一octet but is the Whole matches对字符串。为什么!!!!!!!!!!!!!!!因为茶是贪婪和贪婪。+匹配每个字符是192.168.1.1 matches中直到它为the end of the字符串。This is the important位!!!!!!!!!!!!!!!现在它开始的时间,直到一个字符backtrack(EN for the 3rd在比赛里找到自己的令牌()。P></
if the text文件和字符串到4GB was at the start 192.168.1.1,你可能会easily see how this backtracking会安问题的原因。P></
不要让贪婪的正则表达式(懒惰)在把贪婪的搜索你的问题后e.g马克*???+?2什么是发生在现在的令牌(+?)正则表达式在比赛里找到自己的动作,然后在tries the next character令牌令牌("b)比2(+?)我知道creeps gingerly。恩在。P></
贪婪的匹配。正则表达式的默认行为是贪婪。这意味着它试图尽可能地提取,直到它符合一个模式,即使一个较小的部分在语法上是足够的。
例子:
1 2 3 4 | import re text ="<body>Regex Greedy Matching Example </body>" re.findall('<.*>', text) #> ['<body>Regex Greedy Matching Example </body>'] |
它提取了整个字符串,而不是匹配到第一次出现">"。这是regex的默认贪婪或"全力以赴"行为。
另一方面,懒惰的匹配"尽可能少"。这可以通过在模式末尾添加一个
例子:
1 2 | re.findall('<.*?>', text) #> ['<body>', '</body>'] |
如果只想检索第一个匹配项,请改用搜索方法。
1 2 | re.search('<.*?>', text).group() #> '<body>' |
来源:python regex示例
尝试理解以下行为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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); //"" |