为什么这个正则表达式不贪婪?
在这个正则表达式
$line = 'this is a regular expression';
$line =~ s/^(w+)b(.*)b(w+)$/$3 $2 $1/;
print $line;
为什么2美元等于" is a regular "
? 我的思考过程是(。*)应该是贪婪的并且匹配所有字符,直到行尾,因此$ 3将是空的。
虽然这没有发生。 正则表达式匹配器在最后一个单词边界之前以某种方式停止,并在最后一个单词边界之后填充$ 3,并将字符串的其余部分发送到$ 2。
任何解释? 谢谢。
使用此正则表达式时, $3
不能为空,因为相应的捕获组是(w+)
,它必须至少匹配一个单词字符,否则整个匹配将失败。
那么会发生什么是(.*)
匹配“ is a regular expression
”, b
匹配字符串的结尾,并且(w+)
无法匹配。 正则表达式引擎然后回溯到(.*)
匹配“ is a regular "
(注意匹配包含空格), b
匹配e
之前的单词边界, (w+)
匹配“ expression
”。
如果将(w+)
更改为(w*)
那么最终会得到您期望的结果,其中(.*)
会消耗整个字符串。
贪婪并不意味着它会匹配绝对的一切。 它只是意味着它可以尽可能多地使用正则表达式,并且仍然有正则表达式的成功 。
这意味着,由于您在组3中使用+
,它不能为空,并且仍然成功,因为+
意味着1或更多 。
如果你想让3变为空,只需将(w+)
更改为(w?)
。 从那以后?
意味着0或1它可以是空的,因此贪婪.*
占用一切。 注意:由于perl处理线的方式,这似乎只适用于Perl。
为了使正则表达式匹配整个字符串, ^(w+)b
要求整个第一个单词是1
。 同样, b(w+)$
要求整个最后一个单词是3
。 因此,无论多么贪婪(.*)
,它只能捕获'是一个常规',否则模式将不匹配。 在匹配字符串的某个时候, .*
可能占用了整个'是一个正则表达式',但是后来它发现它必须回溯并让w+
也匹配它。