sub line-and-column(Match $m) {
my $line = ($m.orig.substr(0, $m.from).split("\n")).elems;
# RAKUDO workaround for RT #70003, $m.orig.rindex(...) directly fails
my $column = $m.from - ('' ~ $m.orig).rindex("\n", $m.from);
$line, $column;
}
my $s = "the quick\nbrown fox jumped\nover the the lazy dog";
my token word { \w+ [ \' \w+]? }
my regex dup { <word> \W+ $<word> }
if $s ~~ m/ <dup> / {
my ($line, $column) = line-and-column($/);
say "Found '{$<dup><word>}' twice in a row";
say "at line $line, column $column";
}
# output:
# Found 'the' twice in a row
# at line 3, column 6
Every regex match returns an object of type Match. In boolean context, a
match object returns True for successful matches and False for failed
ones. Most properties are only interesting after successful matches.
The orig method returns the string that was matched against. The from
and to methods return the positions of the start and end points of the
match.
In the previous example, the line-and-column function determines the line
number in which the match occurred by extracting the string up to the match
position ($m.orig.substr(0, $m.from)), splitting it by newlines, and
counting the elements. It calculates the column by searching backwards from
the match position and calculating the difference to the match position.
Using a match object as an array yields access to the positional captures.
Using it as a hash reveals the named captures. In the previous example,
$<dup> is a shortcut for $/<dup> or $/{ 'dup' }. These
captures are again Match objects, so match objects are really trees of
matches.
The caps method returns all captures, named and positional, in the order in
which their matched text appears in the source string. The return value is a
list of Pair objects, the keys of which are the names or numbers of the
capture and the values the corresponding Match objects.
if 'abc' ~~ m/(.) <alpha> (.) / {
for $/.caps {
say .key, ' => ', .value;
}
}
# Output:
# 0 => a
# alpha => b
# 1 => c
In this case the captures occur in the same order as they are in the regex,
but quantifiers can change that. Even so, $/.caps follows the ordering of
the string, not of the regex. Any parts of the string which match but not as
part of captures will not appear in the values that caps returns.
To access the non-captured parts too, use $/.chunks instead. It returns
both the captured and the non-captured part of the matched string, in the same
format as caps, but with a tilde ~ as key. If there are no overlapping
captures (as occurs from look-around assertions), the concatenation of all the
pair values that chunks returns is the same as the matched part of the
string.