如何在另一个正则表达式的评估中保留$+
,$-
,$&
或$'
等正则表达式变量?
/(\w)\s(\w)/ # First regex
say "Found a b" if $1 =~ /b/;
say "$1, $2" # Match from the first regex
对于小型handlebars解析器,我想评估两个级联regex。第一个标识标记,第二个标记获取标记的性质。
所以我写了这个:
my $out = '';
while(/\{\{(?<tag>.*?)\}\}/g) {
if($+{tag} =~ /^\#(?<helper>\w+)\s+(?<parameters>.*)$/) {
# Do something
}
$_ = $`.($data{$+{tag}} // $+{tag}).$';
}
在这种特殊情况下,我想在执行另一个正则表达式后使用第一个正则表达式的结果,这个正则表达式破坏了正则表达式变量($+
,$-
,$&
,{{1 },...)。
我知道我可以让这个例子使用如下所示的中间存储。然而,这不是这个问题的主要话题。
$'
所以,我想知道我是否可以简单地说:
- 避免第二个正则表达式破坏正则表达式变量,或
- 一次保存所有相关的正则表达式变量?
醇>
我不是在讨论这里使用的实现或方法。只有上述问题才有意义。
以下是我解析mustache个代码的方法。下一步将解析帮助程序,列表和哈希键,并尽可能简化所有内容......
push @regex, {match => $&, prematch => $`, #...
};
答案 0 :(得分:3)
Regexp::Result会捕获$1
,$2
,pos
以及所有优秀的标点符号变量,看起来就像您需要的那样。 (它不会捕获效率低下的标点符号变量$&
,$'
和美元反引号,因为如果您在任何地方使用它们,都会导致所有正则表达式匹配产生性能损失。)
对于while
循环,您可能还会发现Regexp::Flow非常有用,具体取决于您最终在该循环中执行的操作。它为您创建Regexp :: Result对象并将它们传递给coderef。
披露:我是两个模块的作者
如果您需要它们,可以使用${^MATCH}
,${^PREMATCH}
,${^POSTMATCH}
而不是三个效率低下的变量,只要您在执行时使用/p
标记即可正则表达式。使用Regexp :: Result,您可以使用$rr->match
等获取它们
为了完整性,如果您只需要编号的捕获而不需要其他内容,Data::Munge会提供一个函数submatches
。
答案 1 :(得分:3)
正则表达式变量已本地化到它们出现的块中,因此只需将第二个正则表达式嵌套在一个块中:
$_ = 'b c';
/(\w)\s(\w)/; # First regex
{
say "Found a b" if $1 =~ /b/;
}
say "$1, $2" # Match from the first regex
或最低限度地使其成为...if do { $1 =~ /b/ };
。
答案 2 :(得分:0)
我不熟悉把手,但似乎使用可选的非捕获组可以简化您的代码:
use strict;
use warnings;
use 5.010;
while (<DATA>) {
my ($tag, $helper, $params) = $_ =~ /{{ (\w+) (?: \s+ (\w+) \s+ (\w+) )? }}/gx;
say $helper if defined $helper;
say $params if defined $params;
}
__DATA__
{{foo}}
{{foo bar baz}}