在这个正则表达式中
$line = 'this is a regular expression';
$line =~ s/^(\w+)\b(.*)\b(\w+)$/$3 $2 $1/;
print $line;
为什么$ 2等于" is a regular "
?我的思维过程是(。*)应该贪婪并匹配所有字符,直到行结束,因此$ 3将为空。
任何解释? 谢谢。
答案 0 :(得分:15)
$3
不能为空,因为相应的捕获组为(\w+)
,必须至少匹配一个单词字符,否则整个匹配将失败。
所以会发生(.*)
匹配“is a regular expression
”,\b
匹配字符串的结尾,(\w+)
无法匹配。然后正则表达式引擎回溯到(.*)
匹配“is a regular "
(请注意匹配包含空格),\b
匹配e
之前的字边界,(\w+)
匹配“expression
”。
如果您将(\w+)
更改为(\w*)
,那么您将得到预期的结果,其中(.*)
会消耗整个字符串。
答案 1 :(得分:6)
贪婪并不意味着它绝对匹配所有东西。它只是意味着它可以尽可能多地并且仍然具有正则表达式成功。
这意味着,由于您在第3组中使用+
,因此它不能为空且仍然成功,因为+
表示 1或更多。
如果您希望3为空,只需将(\w+)
更改为(\w?)
即可。现在,因为?
表示0或1,它可以为空,因此贪婪的.*
会占用所有内容。注意:这似乎仅适用于Perl,因为perl处理行。
答案 2 :(得分:1)
为了使正则表达式与整个字符串匹配,^(\w+)\b
要求整个第一个单词为\1
。同样,\b(\w+)$
要求整个最后一个单词为\3
。因此,无论多么贪婪(.*)
,它只能捕获'是常规',否则模式将不匹配。在匹配字符串的某个时刻,.*
可能确实占用了整个'是一个正则表达式',但后来发现它必须回溯并让\w+
得到它的匹配。
答案 3 :(得分:0)
你编写正则表达式的方式无论.*
是贪婪还是非贪婪都无关紧要。
它仍然会匹配。
原因是您在\b
和.*
之间使用了\w+
。
use strict;
use warnings;
my $string = 'this is a regular expression';
sub test{
my($match,$desc) = @_;
print '# ', $desc, "\n" if $desc;
print "test( qr'$match' );\n";
if( my @elem = $string =~ $match ){
print ' 'x4,'[\'', join("']['",@elem), "']\n\n"
}else{
print ' 'x4,"FAIL\n\n";
}
}
test( qr'^ (\w+) \b (.*) \b (\w+) $'x, 'original' );
test( qr'^ (\w+) \b (.*+) \b (\w+) $'x, 'extra-greedy' );
test( qr'^ (\w+) \b (.*?) \b (\w+) $'x, 'non-greedy' );
test( qr'^ (\w+) \b (.*) \b (\w*) $'x, '\w* instead of \w+' );
test( qr'^ (\w+) \b (.*) (\w+) $'x, 'no \b');
test( qr'^ (\w+) \b (.*?) (\w+) $'x, 'no \b, non-greedy .*?' );
# original
test( qr'(?^x:^ (\w+) \b (.*) \b (\w+) $)' );
['this'][' is a regular ']['expression']
# extra-greedy
test( qr'(?^x:^ (\w+) \b (.*+) \b (\w+) $)' );
FAIL
# non-greedy
test( qr'(?^x:^ (\w+) \b (.*?) \b (\w+) $)' );
['this'][' is a regular ']['expression']
# \w* instead of \w+
test( qr'(?^x:^ (\w+) \b (.*) \b (\w*) $)' );
['this'][' is a regular expression']['']
# no \b
test( qr'(?^x:^ (\w+) \b (.*) (\w+) $)' );
['this'][' is a regular expressio']['n']
# no \b, non-greedy .*?
test( qr'(?^x:^ (\w+) \b (.*?) (\w+) $)' );
['this'][' is a regular ']['expression']