With perl (and almost any regex flavour), every group is numbered sequentially.
So for example, this code:
'bar' =~ m/(foo)|(bar)/;
print $1 // 'x'; # (1-based index)
print $2 // 'x'; # (1-based index)
prints xbar
However, with Raku it behaves like there was a branch reset group wrapping the whole regex:
'bar' ~~ m/(foo)|(bar)/;
print $0 // 'x'; # (0-based index)
print $1 // 'x'; # (0-based index)
prints barx
I'm ok with this behaviour :). However, it is sometimes useful to know which group was captured under an alternation.
How can I know the group with raku?
There are a few ways to do, with varying degrees of utility.
One way would be to explicitly tell Raku what you want the numbers to be:
'bar' ~~ m/$1=(foo)|$2=(bar)/;
If you extend the regex, counting will continue at $3.
A less-recommendable way to do this would be to sneak in an extra set of parentheses:
'bar' ~~ m/(foo)|()(bar)/;
foo
will match the first one in $0 and $1 will be undefined, and bar
will match the $1 with $0 being empty (but not undefined). TIMTOWTDI but this is not a good one ;-)
Another way could be to use a flag:
my $flag;
'bar' ~~ m/(foo {$flag = 'first'} ) | (bar {$flag = 'second'} )/;
The flag will be set based on the match. This can actually be a not-terrible way to do things, especially if your flag is binary and you will have some logic that you'll run over it.
Another similar way would be to take advantage of the .make
/.made
that's normally used in action classes, but can still be used inline too:
'bar' ~~ m/(foo {make 'first'} ) | (bar {make 'second'} )/;
say $0.made; # 'second'
This one is nice if you have a lot of metadata you want to associate with it (but probably overkill for just knowing which one was chosen).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With