5.10.0 版引入了命名捕获组,可用于匹配非平凡模式。
(?'NAME'pattern)
(?<NAME>pattern)
一个命名的捕获组。在每个方面都与普通的捕获括号相同,()
但另外一个事实是该组可以在各种正则表达式构造(例如\g{NAME}
)中按名称引用,并且可以在成功匹配后通过名称访问%+
or %-
。有关和哈希的更多详细信息,请参见perlvar 。%+
%-
如果多个不同的捕获组具有相同的名称,则$+{NAME}
将引用匹配中最左侧定义的组。
形式(?'NAME'pattern)
和(?<NAME>pattern)
是等价的。
命名捕获组允许我们在正则表达式中命名子模式,如下所示。
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;
像这样使用它
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";
}
输出:
$ ./blocks-demo
时间=[00:00]
描述=[[[
东西
]]]
时间=[00:01]
描述=[[[
更多东西
多线
去
]]]
时间=[00:02]
描述=[[[
仍然
有
]]]