Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raku: One line expression to capture group from string?

Tags:

string

raku

I am capturing a number from a string thus:

my $n1;
if $string1 ~~ /(<[0..4]>)$/ {
    $n1 = $0;
} else {
    put "$string1 failed regex.";
    die;
}

which is a lot of lines, but I can copy and edit strings in a single line thus:

my $string2 = $group2.subst(/<[0..4]>$/, '');

I'm still learning raku/perl6, and I've looked through https://docs.perl6.org/type/Str and it doesn't look like Raku can do this... but I'm not sure.

is there a way that I can capture a substring in a single line, similar to the first code sample above?

I do this process repeatedly in my scripts, and it would really shorten my scripts

like image 331
con Avatar asked Nov 21 '19 19:11

con


People also ask

How do you write a raku program?

A Raku program consists of zero or more statements. A statement ends with a semicolon or a curly brace at the end of a line. In Raku, single line comments start with a single hash character # and extend until the end of the line. Raku also supports multi-line/embedded comments.

What is a regular expression called in raku?

In acknowledgement of this, and in an attempt to disambiguate, a regular expression in Raku is normally referred to as a regex (from: reg ular ex pression), a term that is also in common use in other programming languages. In Raku, regexes are written in a domain-specific language, i.e. a sublanguage or slang.

What is the difference between a statements and comments in raku?

A statement ends with a semicolon or a curly brace at the end of a line. In Raku, single line comments start with a single hash character # and extend until the end of the line. Raku also supports multi-line/embedded comments. The compiler doesn't evaluate comments as program text and they're only intended for human readers.

How do you sort players by score in raku?

A block is a self-contained piece of Raku code with an optional signature (the -> $line part). The simplest way to sort the players by score would be @names.sort ( { %matches {$_} }), which sorts by number of matches won. However Ana and Dave have both won two matches.


2 Answers

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.

like image 71
Jonathan Worthington Avatar answered Oct 08 '22 12:10

Jonathan Worthington


Maybe .match is what you are looking for.

my $string1='4';
my $n2 = $string1.match(/(<[0..4]>)$/) // die 'error';
say $n2.values;
like image 22
LuVa Avatar answered Oct 08 '22 12:10

LuVa