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;

Tags:

String

Raku