我正在尝试使用全局修饰符从字符串中提取匹配的部分。
考虑:
my $a="A B C";
my $b="A B C";
foreach ($a =~ /(\w)/g) {
print "$1\n";
}
while ($b =~ /(\w)/g) {
print "$1\n";
}
Run Code Online (Sandbox Code Playgroud)
输出:
C
C
C
A
B
C
Run Code Online (Sandbox Code Playgroud)
我很迷惑; 为什么while循环有效,而foreach循环无效?(它打印C三遍)。
该声明
foreach ($a =~ /(\w)/g)
Run Code Online (Sandbox Code Playgroud)
评估列表上下文中的正则表达式,并迭代列表中的每个项目。$1是构建列表时括号中捕获的最后一个内容。以下应该有效:
foreach my $matched ($a =~ /(\w)/g) {
print "$matched\n";
}
Run Code Online (Sandbox Code Playgroud)
但是,该while语法通常是最好的,因为它不构造和存储该临时列表。
简而言之:将第一个循环的主体更改为print "$_\n".
当全局正则表达式匹配用作列表时,它评估为所有捕获的列表(此处:)qw(A B C)。该foreach循环遍历这个列表,并设置$_在依次每个项目。但是,$1指向最后(成功)匹配的第一个捕获组。由于匹配列表是在循环开始之前生成的,因此这将始终指向最后一个匹配。
当全局正则表达式匹配用作 a 中的迭代器时while,它匹配正则表达式,如果成功执行循环体,则再次尝试。因为当时只产生一个匹配,所以$1总是指当前匹配中的第一个捕获组。