Version 5.10.0 introduces capture group names that are useful for matching non-trivial patterns.
(?'NAME'pattern)
(?<NAME>pattern)
Named capture group. In all respects, it is identical to the usual parentheses () , but for the additional fact that a group can be called by name in various regular expression constructs (for example, \g{NAME} ), and they can be accessed by name after a successful match with %+ or %- . See perlvar for %+ and %- hashes for more details.
If several different capture groups have the same name, then $+{NAME} will refer to the leftmost defined group in the match.
The shapes (?'NAME'pattern) and (?<NAME>pattern) equivalent.
Named capture groups allow us to specify subpatterns in a regular expression, as shown below.
use 5.10.0; # named capture buffers my $block_pattern = qr/ (?<time>(?&_time)) (?&_sp) (?<desc>(?&_desc)) (?(DEFINE) # timestamp at logical beginning-of-line (?<_time> (?m:^) [0-9][0-9]:[0-9][0-9]) # runs of spaces or tabs (?<_sp> [ \t]+) # description is everything through the end of the record (?<_desc> # s switch makes . match newline too (?s: .+?) # terminate before optional whitespace (which we remove) followed # by either end-of-string or the start of another block (?= (?&_sp)? (?: $ | (?&_time))) ) ) /x;
Use it as in
my $text = '00:00 stuff 00:01 more stuff multi line and going 00:02 still have '; while ($text =~ /$block_pattern/g) { print "time=[$+{time}]\n", "desc=[[[\n", $+{desc}, "]]]\n\n"; }
Output:
$ ./blocks-demo
time = [00:00]
desc = [[[
stuff
]]]
time = [00:01]
desc = [[[
more stuff
multi line
and going
]]]
time = [00:02]
desc = [[[
still
have
]]]
Greg bacon
source share