Raku: One line expression to capture group from string?
It is possible to use a destructuring bind to extract parts of a match into variables. For the example given, we can extract the matched part like this:
my ($n) := "abc123" ~~ /(<[1..4]>+)$/;
say $n; # 「123」
This scales up to extracting multiple parts of the match:
my ($s, $n) := "abc123" ~~ /(<[a..z]>+)(<[1..4]>+)$/;
say $s; # 「abc」
say $n; # 「123」
Captured things in Raku are themselves Match
objects, but it's possible to use coercion in the destructuring too, in order to turn it into an integer:
my (Int() $n) := "abc123" ~~ /(<[1..4]>+)$/;
say $n; # 123
say $n.WHAT; # (Int)
It even works with named matches (a bit artificial here, but handy if you are making subrule calls):
my (:$s, :$n) := "abc123" ~~ /$<s>=(<[a..z]>+) $<n>=(<[1..4]>+)$/;
say $s; # 「abc」
say $n; # 「123」
The obvious downside of this is that one can get an exception if it fails to match. Thankfully, however, this can be combined with an if
:
if "abc123" ~~ /(<[a..z]>+)(<[1..4]>+)$/ -> ($s, $n) {
say $s;
say $n;
}
And the same syntax works, because a destructuring bind is actually just an application of signatures.
Maybe .match is what you are looking for.
my $string1='4';
my $n2 = $string1.match(/(<[0..4]>)$/) // die 'error';
say $n2.values;