Regexes & grammars · lesson 15 of 18

Regexes

Match with ~~, capture with parentheses or names, and rewrite with subst.

The smartmatch operator ~~ matches a string against a regex. Whitespace inside a regex is insignificant, and literal text goes in quotes:

my $line = 'error: disk full';
if $line ~~ / 'error:' / {
    say 'something went wrong';
}
say so 'camelia' ~~ / me /;
Output
something went wrong
True

so boolifies the match — handy for a quick yes/no.

Captures #

Parentheses capture into $0, $1, …; prefix a group with a name and it lands in $<name> instead. \d matches a digit, + means one-or-more:

if '2026-07-23' ~~ / (\d+) '-' (\d+) '-' (\d+) / {
    say "year { ~$0 }, month { ~$1 }, day { ~$2 }";
}

if 'Bond, James Bond' ~~ / $<last> = [\w+] ',' \s $<first> = [\w+] / {
    say "{ ~$<first> } { ~$<last> }";
}
Output
year 2026, month 07, day 23
James Bond

Substitution and global matching #

.subst replaces (with :g for every occurrence), and m:g/.../ finds all matches:

say 'banana'.subst('a', 'o', :g);
my @nums = ('10 cats, 7 dogs, 3 parrots' ~~ m:g/ \d+ /);
say @nums.map(+*).sum;
Output
bonono
20

+* turns each match into a number — "whatever, numified".

Try it #

Extract the user and host from the address with named captures. (\w+ matches a word; you'll need '@' and '.' as quoted literals.)

if 'camelia@raku.org' ~~ / / {
    say ~$<user>;
    say ~$<host>;
}
Show a solution
if 'camelia@raku.org' ~~ / $<user> = [\w+] '@' $<host> = [\w+ '.' \w+] / {
    say ~$<user>;
    say ~$<host>;
}
Output
camelia
raku.org