在 foreach 循环中使用全局修饰符从 Perl 正则表达式中提取匹配项

7
我正在尝试使用全局修饰符从字符串中提取匹配的部分。
考虑以下示例:
my $a="A B C";
my $b="A B C";

foreach ($a =~ /(\w)/g) {
    print "$1\n";
}
while ($b =~ /(\w)/g) {
    print "$1\n";
}

输出:

C
C
C
A
B
C

我有点困惑:为什么while循环能够工作,而foreach循环不能?(它会打印C三次。)

2个回答

8
简而言之:将第一个循环体的主体更改为 print "$_\n"
当全局正则表达式匹配用作列表时,它会评估所有捕获组成的列表(此处为qw(A B C))。foreach循环遍历该列表,并依次将$_设置为每个项目。但是,$1指向最后一个(成功)匹配的第一个捕获组。由于匹配列表在循环开始之前生成,因此这将始终指向最后一次匹配。
当全局正则表达式匹配被用作while中的迭代器时,它会匹配正则表达式并在成功执行循环主体后再尝试匹配。由于每次只产生一个匹配,$1始终指向当前匹配的第一个捕获组。

5
声明
foreach ($a =~ /(\w)/g)

在列表上下文中评估正则表达式,并遍历列表中的每个项。 $1 是构建列表时括号中捕获的最后一个内容。以下代码应该可以工作:

foreach my $matched ($a =~ /(\w)/g) {
  print "$matched\n";
}

然而,while语法通常最好,因为它不会构建和存储临时列表。

1
如果提到while循环的内存效率优于foreach循环,将会得到加1分。对于大字符串,使用foreach循环可能会占用一些内存。 - user3183018

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接