我通常使用以下正则表达式进行平衡匹配
my $np;
$np = qr{
\{
(?:
(?> [^\{\}]+ )
|
(??{ $np })
)*
\}
}x;
例如
my $text = "{string{string1}{string2}}";
$text =~ /($np)/;
问题是,是否可以扩展它,使其在string
等包含一个}
或{
以反斜杠开头时也匹配。这意味着在执行平衡匹配时,应忽略转义的花括号(与其他任何字符一样对待)。
当然。您要做的就是将“任何其他字符”表达式更改为既可以接受转义括号的表达式,也可以将“除括号之外的任何东西”的表达式更改为可接受的表达式
(?> (?: \\[()] | [^{}] )+ )
还要注意,该(??{ $np })
构造早已被取代,如果您使用的是Perl 5版本10或更高版本,则可以使用内置的递归机制,从而(?R)
从头开始递归整个表达式。
use strict;
use warnings;
use 5.010;
my $np = qr{
\{
(?:
(?>
(?: \\\\ | \\} | \\} | [^{}] )*
)
|
(?R)
)*
\}
}xs;
my $text = '{string{string1 \} test}{string2}}';
$text =~ /($np)/;
say $1;
输出
{string{string1 \} test}{string2}}
请注意,我不认为“无回溯”构造(?> ... )
在这里有用。已经指定了中间字符串,因此后面的所有内容都必须与下一个标记或字符串的末尾匹配,并且不存在非贪婪的通配符。但是我确信它没有害处,所以我把它留了下来。
更新
为了在第一个常规大括号之前允许使用转义的开括号,最简单的方法是为“ regular character”编写一个单独的正则表达式,除了正则括号或闭合的括号外,或者其他任何内容均不得转义。
像这样
use strict;
use warnings;
use 5.010;
my $reg_char = qr/(?: \\. | [^{}] )/xs; # Define what *isn't* a brace
my $np = qr{
\{
(?:
(?> $reg_char* )
|
(?R)
)*
\}
}x;
my $text = 'aaa \{ bbb {string{string1 \} test}{string2}}';
die unless $text =~ / $reg_char* ($np) /x;
say $1;
输出
{string{string1 \} test}{string2}}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句