tjw*_*992 6 regex perl regex-recursion
我试图使用Perl正则表达式捕获C风格代码块之前和之后的一些文本.到目前为止,这就是我所拥有的:
use strict;
use warnings;
my $text = << "END";
int max(int x, int y)
{
if (x > y)
{
return x;
}
else
{
return y;
}
}
// more stuff to capture
END
# Regex to match a code block
my $code_block = qr/(?&block)
(?(DEFINE)
(?<block>
\{ # Match opening brace
(?: # Start non-capturing group
[^{}]++ # Match non-brace characters without backtracking
| # or
(?&block) # Recursively match the last captured group
)* # Match 0 or more times
\} # Match closing brace
)
)/x;
# $2 ends up undefined after the match
if ($text =~ m/(.+?)$code_block(.+)/s){
print $1;
print $2;
}
Run Code Online (Sandbox Code Playgroud)
我遇到第二个捕获组在比赛后没有初始化的问题.在DEFINE块之后没有办法继续正则表达式吗?我认为这应该工作正常.
$2 应该包含代码块下面的注释,但它没有,我找不到一个很好的理由,为什么这不起作用.
捕获组按照它们在正则表达式中出现的顺序从左到右编号,而不是按照它们匹配的顺序。这是正则表达式的简化视图:
m/
(.+?) # group 1
(?: # the $code_block regex
(?&block)
(?(DEFINE)
(?<block> ... ) # group 2
)
)
(.+) # group 3
/xs
Run Code Online (Sandbox Code Playgroud)
命名组也可以作为编号组进行访问。
第2组是block小组。但是,该组仅用作命名子模式,而不用作捕获。因此,$2捕获值是 undef。
因此,代码块后面的文本将存储在 capture 中$3。
有两种方法可以处理这个问题:
对于复杂的正则表达式,仅使用命名捕获。一旦您从正则表达式对象组装正则表达式,或者如果捕获是有条件的,则认为正则表达式很复杂。这里:
if ($text =~ m/(?<before>.+?)$code_block(?<afterwards>.+)/s){
print $+{before};
print $+{afterwards};
}
Run Code Online (Sandbox Code Playgroud)将所有定义放在最后,这样它们就不会弄乱您的捕获编号。例如,您的$code_block正则表达式只会定义一个命名模式,然后您可以显式调用该模式。
| 归档时间: |
|
| 查看次数: |
364 次 |
| 最近记录: |