Answers:
贪婪将消耗尽可能多的东西。从http://www.regular-expressions.info/repeat.html中,我们看到了尝试将HTML标签与匹配的示例<.+>
。假设您具有以下条件:
<em>Hello World</em>
您可能会认为<.+>
(.
意味着任何非换行符,并且+
意味着一个或多个)仅与<em>
和匹配,而</em>
实际上它会非常贪婪,并且从第一个<
到最后一个>
。这意味着它将匹配<em>Hello World</em>
而不是您想要的。
使其变得懒惰(<.+?>
)可以防止这种情况。通过在?
之后添加+
,我们告诉它重复的次数越少越好,因此>
它遇到的第一个就是我们要停止匹配的位置。
我鼓励您下载RegExr,这是个很棒的工具,可以帮助您探索正则表达式-我一直都在使用它。
<[^>]+>
regex101.com/r/lW0cY6/1
“ Greedy”表示匹配最长的字符串。
“惰性”表示匹配最短的字符串。
例如,贪婪h.+l
匹配'hell'
中,'hello'
而懒惰h.+?l
匹配中'hel'
。
h.+l
比赛'helol'
,'helolo'
但懒惰的h.+?l
比赛'hel'
。
x?
手段x
是可选的,但+?
语法不同。这意味着不要再寻找匹配的东西-惰性匹配。
?
表示可选,+?
表示惰性。因此,\+?
手段+
是可选的。
+-------------------+-----------------+------------------------------+
| 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 |
+-------------------+-----------------+------------------------------+
添加一个?使量词变得不贪心即懒惰。
实施例:
测试字符串:计算器
贪婪reg表达式:s.*o
输出:stackoverflo瓦特
懒惰reg表达式:s.*?o
输出:stacko verflow
re.match('(f)?(.*)', 'food').groups()
到re.match('(f)??(.*)', 'food').groups()
。在后者中,(f)??
即使可以,也不会匹配前导“ f”。因此,“ f”将与第二个“。*”捕获组匹配。我确定您可以使用'{n}?太。诚然,这两个都是很少使用的。
据我所知,大多数正则表达式引擎默认情况下都是贪婪的。在量词末尾添加问号将启用延迟匹配。
正如@Andre S在评论中提到的那样。
关于贪婪和懒惰,请参考以下示例。
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");
}
}
}
I'm greeedy and I want 100000000 dollars. This is the most I can get.
I'm too lazy to get so much money, only 100 dollars is enough for me
取自www.regular-expressions.info
贪婪:贪婪的量词首先尝试尽可能多地重复令牌,然后逐渐放弃匹配,因为引擎回溯以找到整体匹配。
懒惰:懒惰量词第一重复令牌根据需求,以及双面逐渐扩大通过正则表达式引擎回溯找到一个整体搭配几次。
贪婪的匹配。正则表达式的默认行为是贪婪。这意味着即使语法上较小的部分,它也会尝试尽可能多地提取直到符合模式为止。
例:
import re
text = "<body>Regex Greedy Matching Example </body>"
re.findall('<.*>', text)
#> ['<body>Regex Greedy Matching Example </body>']
它没有提取匹配到第一次出现的'>',而是提取了整个字符串。这是正则表达式的默认贪婪或“全部使用”行为。
另一方面,惰性匹配 “花最少的钱 ”。这可以通过?
在模式的末尾添加a来实现。
例:
re.findall('<.*?>', text)
#> ['<body>', '</body>']
如果只想检索第一个匹配项,请改用搜索方法。
re.search('<.*?>', text).group()
#> '<body>'
最好以示例显示。串。192.168.1.1
和一个贪婪的正则表达式\b.+\b
您可能会认为这会给您第一个八位位组,但实际上与整个字符串匹配。为什么?因为。+是贪婪的,并且贪婪的匹配匹配其中的每个字符,192.168.1.1
直到到达字符串的末尾。这是重要的一点!现在,它开始一次回溯一个字符,直到找到与第三个标记(\b
)相匹配的字符为止。
如果字符串开头是一个4GB的文本文件和192.168.1.1,则可以很容易地看到这种回溯将如何引起问题。
为了使正则表达式变得非贪婪(懒惰),请在贪婪搜索之后打一个问号,例如
*?
??
+?
现在发生的是令牌2(+?
)找到一个匹配项,正则表达式沿着字符移动,然后尝试下一个令牌(\b
)而不是令牌2(+?
)。因此它会小心翼翼地爬行。
如果在那里,他们会来接走。他们将全部拿走:
例如,IRS与此正则表达式匹配: .*
$50,000
-国税局会全力以赴。那些贪婪的.*{4}?
ERS
参见示例:regexr.com/4t27f
另一方面,如果我要求退税,美国国税局突然变得不贪心,他们使用此量词:
(.{2}?)([0-9]*)
反对这种表达方式:$50,000
第一组是非个性化的,只匹配$5
–因此我得到了$5
退款。其余的由山姆大叔带走,浪费了。
参见此处:非贪婪示例。
如果您要匹配表达式的某些部分,则变得很重要。有时您不想匹配所有内容。
尝试了解以下行为:
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); // ""