In Regexes§
See primary documentation in context for Subrules
Just like you can put pieces of code into subroutines, you can also put pieces of regex into named rules.
my regex line { \N*\n } if "abc\ndef" ~~ /<line> def/ { say "First line: ", $<line>.chomp; # OUTPUT: «First line: abc» }
A named regex can be declared with my regex named-regex { body here }
, and called with <named-regex>
. At the same time, calling a named regex installs a named capture with the same name.
To give the capture a different name from the regex, use the syntax <capture-name=named-regex>
. If no capture is desired, a leading dot or ampersand will suppress it: <.named-regex>
if it is a method declared in the same class or grammar, <&named-regex>
for a regex declared in the same lexical context.
Here's more complete code for parsing ini
files:
my regex header { \s* '[' (\w+) ']' \h* \n+ } my regex identifier { \w+ } my regex kvpair { \s* <key=identifier> '=' <value=identifier> \n+ } my regex section { <header> <kvpair>* } my $contents = q:to/EOI/; [passwords] jack=password1 joy=muchmoresecure123 [quotas] jack=123 joy=42 EOI my %config; if $contents ~~ /<section>*/ { for $<section>.list -> $section { my %section; for $section<kvpair>.list -> $p { %section{ $p<key> } = ~$p<value>; } %config{ $section<header>[0] } = %section; } } say %config.raku; # OUTPUT: «{:passwords(${:jack("password1"), :joy("muchmoresecure123")}), # :quotas(${:jack("123"), :joy("42")})}»
Named regexes can and should be grouped in grammars. A list of predefined subrules is here.