Could someone explain why captures (named and un-named) don't seem to work in named regexes? I'm expecting that It is something I'm doing wrong, but if so, I don't see it. Here is captured text from the raku repl as my short-form example.
> my $s = '16.01.2020 09:18 286';
> my $dReg = /^(\d**2)\.(\d**2)\.(\d**4)/;
> $s ~~ /<$dReg>/;
「16.01.2020」
> if $s ~~ /<$dReg>/ { say $0 }
Nil
> my $dReg1 = /^$<day> = (\d**2)\.$<mon> = (\d**2)\.$<year> = (\d**4)/;
/^$<day> = (\d**2)\.$<mon> = (\d**2)\.$<year> = (\d**4)/
> $s ~~ /<$dReg1>/;
「16.01.2020」
> if $s ~~ /<$dReg1>/ { say $<day> }
Nil
> if $s ~~ /^$<day> = (\d**2)\.$<mon> = (\d**2)\.$<year> = (\d**4)/ { say $<day> }
「16」
> if $s ~~ /^(\d**2)\.(\d**2)\.(\d**4)/ { say $0 }
「16」
The problem is at the point the regex is used - that is, the <$dReg>
. Any form of assertion syntax starting with a non-identifier does not capture. The solution is to introduce a name for it to be captured under. For example, this:
my $s = '16.01.2020 09:18 286';
my $dReg = /^(\d**2)\.(\d**2)\.(\d**4)/;
say $s ~~ /<dreg=$dReg>/;
Results in:
「16.01.2020」
dreg => 「16.01.2020」
0 => 「16」
1 => 「01」
2 => 「2020」
You'd then access the captures as $<dreg>[0]
. This is because each level of rule call implies a nesting level in Raku regexes. This is what allows them to scale up to full grammars.
Note that it's entirely fine - and more efficient - to match against the variable containing the regex if that's all you wish to do. In that case, you'll get the captures directly. For example, this:
my $s = '16.01.2020 09:18 286';
my $dReg = /^(\d**2)\.(\d**2)\.(\d**4)/;
say $s ~~ $dReg;
Produces:
「16.01.2020」
0 => 「16」
1 => 「01」
2 => 「2020」
See jnthn's answer.
Another option is to declare a named regex (which isn't the same thing as a variable that has a name and happens to contain a regex). For example:
my $input = 'foo';
my regex dreg { 'foo' }
if $input ~~ /<dreg>/ { say $<dreg> } # 「foo」
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