Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extracting matches from perl regex using global modifier in foreach loop

Tags:

perl

I am trying to extract matched parts from a string using the global modifier.

Consider:

my $a="A B C";
my $b="A B C";

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

Output:

C
C
C
A
B
C

I am confused; why does the while loop work, whereas the foreach loop does not? (It prints C three times).

like image 833
Håkon Hægland Avatar asked Mar 15 '14 13:03

Håkon Hægland


1 Answers

In short: change body of the first loop to print "$_\n".

When a global regex match is used as a list, it evaluates to a list of all captures (here: qw(A B C)). The foreach loop iterates over this list, and sets $_ to each item in turn. However, $1 points to the first capture group of the last (successful) match. As the list of matches is produced before the looping begins, this will point to the last match the whole time.

When a global regex match is used as an iterator in a while, it matches the regex and if successful executed the loop body, then tries again. Because only one match is produced at the time, $1 always refers to the first capture group in the current match.

like image 67
amon Avatar answered Oct 28 '22 11:10

amon