如何递归匹配与多字符分隔符平衡的字符串?
考虑一个LaTeX内联引号,使得2个双提示(``
)标记引号开始的位置,并且2个撇号(\x27\x27
)结束。
以下代码为我提供了``five''
。我想捕获two ``three `four' ``five'' three four'' six
my $str = q|one ``two ``three `four' ``five'' three four'' six'' seven|;
if ( $str =~ /
(
``
(?:
[^`']
|
(?1)
)*
''
)
/x
)
{
print "$1\n";
}
我想它与如何否定有关,而不是字符类([^`']
,而是多字符串。
答案 0 :(得分:6)
(?:(?!PAT)(?s:.))*
是PAT
,[^CHAR]*
是CHAR
,所以
(?:(?!``|'')(?s:.))*
匹配任何不是这两个序列开头的字符。但是,我认为前瞻一点都不贵,所以我相信
(?: [^`']+ | `(?!`) | '(?!') )*
会更便宜。我们得到以下信息:
/
(
``
(
(?: [^`']+ | `(?!`) | '(?!') )*
(?:
(?-2)
(?: [^`']+ | `(?!`) | '(?!') )*
)*
)
''
)
/x
我们可以简化性能下降。
/
(
``
(
(?: [^`']+
| `(?!`)
| '(?!')
| (?-2)
)*
)
''
)
/x
在两个片段中,您要捕获的文字位于$2
。