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?
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.
!:($text =~ /!(.)(?=!)/g);. However, your code outputsaandc, not onlya.my @matches = split "!", "!a!b!c!";