这两个术语是什么?
当前回答
摘自www.regular-expressions.info
贪心:贪心量词首先尝试重复标记尽可能多的次数 尽可能,并逐渐放弃匹配,因为引擎返回寻找 一场全面的比赛。
惰性:惰性量词首先根据需要重复标记的次数,然后 随着引擎通过正则表达式返回到,逐渐扩展匹配 找到一个整体匹配。
其他回答
为了进一步说明懒惰,这里有一个例子,乍一看可能不太直观,但从Suganthan Madhavan Pillai的回答中解释了“逐渐扩大比赛”的想法。
input -> some.email@domain.com@
regex -> ^.*?@$
这个输入的Regex将有一个匹配。乍一看,有人可能会说LAZY match(".*?@")将在第一个@停止,之后它将检查输入字符串结束("$")。按照这个逻辑,有人会得出没有匹配的结论,因为输入字符串在第一个@之后没有结束。
但正如你所看到的,情况并非如此,即使我们使用非贪婪(懒惰模式)搜索,regex也会继续前进,直到它命中秒@并有一个MINIMAL匹配。
最好用例子来说明。字符串。192.168.1.1和一个贪婪的正则表达式\b.+\b 你可能认为这会给你第一个八位元,但实际上是匹配整个字符串。为什么?因为。+是贪婪的,贪婪匹配匹配192.168.1.1中的每个字符,直到它到达字符串的末尾。这是最重要的一点!现在它开始一次回溯一个字符,直到找到与第三个标记(\b)匹配的字符。
如果字符串一个4GB文本文件和192.168.1.1在开始,你可以很容易地看到这个回溯会导致一个问题。
要使正则表达式非贪婪(懒惰),在你的贪婪搜索后放一个问号
*?
??
+?
现在发生的事情是令牌2(+?)找到一个匹配,regex沿着一个字符移动,然后尝试下一个令牌(\b),而不是令牌2(+?)。所以它小心翼翼地爬行着。
试着理解以下行为:
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); // ""
贪婪意味着它将消耗你的模式,直到没有剩下的,它不能再看了。
Lazy会在遇到您请求的第一个模式时立即停止。
我经常遇到的一个常见的例子是\s*-\s*?([0-9]{2}\s*-\s*?[0-9]{7})
第一个\s*被归类为贪婪的,因为有*,它会在遇到数字后寻找尽可能多的空白,然后寻找破折号“-”。第二个s*在哪里?懒惰是因为*的存在吗?这意味着它将查看第一个空白字符并在那里停止。
来自正则表达式
regular中的标准量词 表达式是贪婪的,这意味着它们 尽可能多地匹配,只给予 回视需要进行匹配 正则表达式的剩余部分。 通过使用惰性量词,的 表达式尝试最小匹配 第一。
推荐文章
- 如何从JavaScript中使用正则表达式的字符串中剥离所有标点符号?
- 正则表达式中的单词边界是什么?
- 如何将一个标题转换为jQuery的URL段塞?
- Javascript和regex:分割字符串并保留分隔符
- (grep)正则表达式匹配非ascii字符?
- 如何在保持原始字符串的同时对字符串执行Perl替换?
- 创建正则表达式匹配数组
- *的区别是什么?和。*正则表达式?
- 如何将“camelCase”转换为“Camel Case”?
- 在Java中使用正则表达式提取值
- Java中的正则表达式命名组
- 使用正则表达式搜索和替换Visual Studio代码
- 使用split("|")按管道符号拆分Java字符串
- 替换字符串中第一次出现的模式
- “\d”在正则表达式中是数字吗?