beasy
beasy

Reputation: 1227

Perl Regex Capture Into Array

Why does this code:

my $text = "!a!b!c!";
my @captures = ($text =~ /!(.)!/g);
print "$_\n" foreach @captures;

output only

a
c

?

Expected output:

a
b
c

How can I capture all of them?

Upvotes: 1

Views: 59

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626689

You need to use a look-ahead in order not to consume the second ! and keep it for the next regex engine iteration:

/!(.)(?=!)/g

First, ! is matched, then any symbol but a newline that is right before a ! that is not consumed, the regex engine index stays right before it. So, the next match can start with this !.

Updated code:

my $text = "!a!b!c!";
my @captures = ($text =~ /!(.)(?=!)/g);
print "$_\n" foreach @captures;

Output:

a
b
c

Splitting with ! can turn out a more effecient alternative in the currently posted scenario:

my $text = "!a!b!c!";
my @matches = grep /\S/, split "!", $text;
print "$_\n" foreach @matches;

Note that grep /\S/ will remove empty or whitespace-only elements from the array obtained with split.

Upvotes: 2

Related Questions