递归正则表达式是否理解命名捕获?文档中有一个注释(?{{ code }})
,它是一个独立的子模式,具有自己的一组捕获,在子模式完成时被丢弃,并且有一个注释(?PARNO)
,它“类似于(?{{ code }})
.(?PARNO)
完成后丢弃自己的命名捕获吗?
我正在写关于 Perl 的精通 Perl的递归正则表达式。perlre已经有一个平衡括号的例子(我在 Perl regex 中匹配平衡括号中展示了它),所以我想我会尝试平衡引号:
#!/usr/bin/perl
# quotes-nested.pl
use v5.10;
$_ =<<'HERE';
He said 'Amelia said "I am a camel"'
HERE
say "Matched!" if m/
(
['"]
(
(?:
[^'"]+
|
( (?1) )
)*
)
['"]
)
/xg;
print "
1 => $1
2 => $2
3 => $3
4 => $4
5 => $5
";
这有效,两个引号显示在$1
and中$3
:
Matched!
1 => 'Amelia said "I am a camel"'
2 => Amelia said "I am a camel"
3 => "I am a camel"
4 =>
5 =>
没关系。我明白那个。但是,我不想知道数字。因此,我将第一个捕获组命名为捕获并期待看到我之前在and%-
中看到的两个子字符串:$1
$2
use v5.10;
$_ =<<'HERE';
He said 'Amelia said "I am a camel"'
HERE
say "Matched [$+{said}]!" if m/
(?<said>
['"]
(
(?:
[^'"]+
|
(?1)
)*
)
['"]
)
/xg;
use Data::Dumper;
print Dumper( \%- );
我只看到第一个:
Matched ['Amelia said "I am a camel"']!
$VAR1 = {
'said' => [
'\'Amelia said "I am a camel"\''
]
};
我希望这(?1)
会重复第一个捕获组中的所有内容,包括命名捕获到said
. 我可以通过命名一个新的捕获来解决这个问题:
use v5.10;
$_ =<<'HERE';
He said 'Amelia said "I am a camel"'
HERE
say "Matched [$+{said}]!" if m/
(?<said>
['"]
(
(?:
[^'"]+
|
(?<said> (?1) )
)*
)
['"]
)
/xg;
use Data::Dumper;
print Dumper( \%- );
现在我得到了我的预期:
Matched ['Amelia said "I am a camel"']!
$VAR1 = {
'said' => [
'\'Amelia said "I am a camel"\'',
'"I am a camel"'
]
};
我认为我可以通过将命名的捕获上移一级来解决这个问题:
use v5.10;
$_ =<<'HERE';
He said 'Amelia said "I am a camel"'
HERE
say "Matched [$+{said}]!" if m/
(
(?<said>
['"]
(
(?:
[^'"]+
|
(?1)
)*
)
['"]
)
)
/xg;
use Data::Dumper;
print Dumper( \%- );
但是,这并没有捕捉到较小的子字符串said
:
Matched ['Amelia said "I am a camel"']!
$VAR1 = {
'said' => [
'\'Amelia said "I am a camel"\''
]
};
我想我理解这一点,但我也知道这里有些人实际上接触了实现它的 C 代码。:)
而且,当我写这篇文章时,我认为我应该超载 STORE 领带%-
以找出答案,但是我必须找出如何做到这一点。