这两个术语是什么?
当前回答
最好用例子来说明。字符串。192.168.1.1和一个贪婪的正则表达式\b.+\b 你可能认为这会给你第一个八位元,但实际上是匹配整个字符串。为什么?因为。+是贪婪的,贪婪匹配匹配192.168.1.1中的每个字符,直到它到达字符串的末尾。这是最重要的一点!现在它开始一次回溯一个字符,直到找到与第三个标记(\b)匹配的字符。
如果字符串一个4GB文本文件和192.168.1.1在开始,你可以很容易地看到这个回溯会导致一个问题。
要使正则表达式非贪婪(懒惰),在你的贪婪搜索后放一个问号
*?
??
+?
现在发生的事情是令牌2(+?)找到一个匹配,regex沿着一个字符移动,然后尝试下一个令牌(\b),而不是令牌2(+?)。所以它小心翼翼地爬行着。
其他回答
最好用例子来说明。字符串。192.168.1.1和一个贪婪的正则表达式\b.+\b 你可能认为这会给你第一个八位元,但实际上是匹配整个字符串。为什么?因为。+是贪婪的,贪婪匹配匹配192.168.1.1中的每个字符,直到它到达字符串的末尾。这是最重要的一点!现在它开始一次回溯一个字符,直到找到与第三个标记(\b)匹配的字符。
如果字符串一个4GB文本文件和192.168.1.1在开始,你可以很容易地看到这个回溯会导致一个问题。
要使正则表达式非贪婪(懒惰),在你的贪婪搜索后放一个问号
*?
??
+?
现在发生的事情是令牌2(+?)找到一个匹配,regex沿着一个字符移动,然后尝试下一个令牌(\b),而不是令牌2(+?)。所以它小心翼翼地爬行着。
贪婪匹配。正则表达式的默认行为是贪婪的。这意味着它会尝试提取尽可能多的数据,直到它符合某个模式,即使在语法上只需要较小的部分就足够了。
例子:
import re
text = "<body>Regex Greedy Matching Example </body>"
re.findall('<.*>', text)
#> ['<body>Regex Greedy Matching Example </body>']
它提取了整个字符串,而不是直到' > '第一次出现才匹配。这是regex默认的贪婪或“全部拿走”行为。
另一方面,懒惰匹配“需要的越少越好”。这可以通过添加一个?在图案的最后。
例子:
re.findall('<.*?>', text)
#> ['<body>', '</body>']
如果只希望检索第一个匹配项,则使用search方法。
re.search('<.*?>', text).group()
#> '<body>'
来源:Python Regex Examples
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 |
加一个?给量词,使其不贪婪,即懒惰。
例子: 测试字符串:stackoverflow 贪心reg表达式:s.*o输出:stackoverflow Lazy reg表达式:s.*?O输出:stackoverflow
据我所知,大多数正则表达式引擎默认是贪婪的。在量词末尾添加问号将启用惰性匹配。
正如@Andre S在评论中提到的。
贪婪:继续搜索,直到条件不满足。 Lazy:当条件满足时停止搜索。
参考下面的例子,了解什么是贪婪的,什么是懒惰的。
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 greedy 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");
}
}
}
The result is:
I'm greedy 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
贪婪意味着它将消耗你的模式,直到没有剩下的,它不能再看了。
Lazy会在遇到您请求的第一个模式时立即停止。
我经常遇到的一个常见的例子是\s*-\s*?([0-9]{2}\s*-\s*?[0-9]{7})
第一个\s*被归类为贪婪的,因为有*,它会在遇到数字后寻找尽可能多的空白,然后寻找破折号“-”。第二个s*在哪里?懒惰是因为*的存在吗?这意味着它将查看第一个空白字符并在那里停止。