以下打印ac | a | bbb | c
#!/usr/bin/env perl
use strict;
use warnings;
# use re 'debug';
my $str = 'aacbbbcac';
if ($str =~ m/((a+)?(b+)?(c))*/) {
print "$1 | $2 | $3 | $4\n";
}
似乎失败的匹配不会重置捕获的组变量。 我错过了什么?
感谢,
答案 0 :(得分:15)
似乎失败的匹配不会重置捕获的组变量
那里没有失败的比赛。你的正则表达式匹配字符串罚款。虽然在某些重复中内部组有一些失败的匹配。如果该组在当前重复中不匹配,则每个匹配的组可能会被为该特定组找到的下一个匹配项覆盖,或者保留前一个匹配项的值。
让我们看看正则表达式匹配是如何进行的:
首先(a+)?(b+)?(c)
匹配aac
。由于(b+)?
是可选的,因此不会匹配。在此阶段,每个捕获组包含以下部分:
$1
包含完整匹配 - aac
$2
包含(a+)?
部分 - aa
$3
包含(b+)?
部分 - null
。$4
包含(c)
部分 - c
由于还有一些字符串需要匹配 - bbbcac
。继续进行 - (a+)?(b+)?(c)
次匹配 - bbbc
。由于(a+)?
是可选的,因此不会匹配。
$1
包含完整匹配 - bbbc
。覆盖$1
$2
不匹配。因此,它将包含以前匹配的文字 - aa
$3
这次匹配。它包含 - bbb
$4
匹配c
同样,(a+)?(b+)?(c)
会继续匹配最后一部分 - ac
。
$1
包含完整匹配 - ac
。 $2
这次匹配a
。覆盖$2
中的上一个值。它现在包含 - a
$3
与此时间不匹配,因为没有(b+)?
部分。它与上一场比赛相同 - bbb
$4
匹配c
。覆盖上一场比赛的值。它现在包含 - c
。现在,字符串中没有任何内容可供选择。所有捕获组的最终值为:
$1
- ac
$2
- a
$3
- bbb
$4
- c
。答案 1 :(得分:1)
奇怪的是,这似乎是“预期的”行为。以下是perlre文档的引用:
注意:Perl中的失败匹配不会重置匹配变量,这样可以更轻松地编写测试一系列更具体案例的代码,并记住最佳匹配。
答案 2 :(得分:0)
对于括号分组,/(\d+)/
此documentation表示要使用 \1 \2 ...
或\g{1} \g{2}
。在替换正则表达式部分中使用$1 or $2...
将导致如下错误:在模式中找到的标量
# Example to turn a css href to local css.
# Transforms <link href="http://..." into <link href="css/..."
# ... inside a loop ...
my $localcss = $_; # one line from the file
$localcss =~ s/href.+\/([^\/]+\.css")/href="css\/\1/g ;