gpt4 book ai didi

regex - 完成后,Perl的 `(?PARNO)`是否会丢弃其自己的命名捕获?

转载 作者:行者123 更新时间:2023-12-03 08:49:59 25 4
gpt4 key购买 nike

递归正则表达式可以理解命名捕获吗?在(?{{ code }})的文档中有一个注释,它是一个独立的子模式,具有自己的捕获集,在完成子模式后将其丢弃,并且在(?PARNO)中有一个注释,其“类似于(?{{ code }})(?PARNO)是否在丢弃时保留了自己的命名捕获完成?

我正在写Perl的Mastering Perl递归正则表达式。 perlre已经有一个使用平衡括号的示例(我在Matching balanced parenthesis in 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$3中:
Matched!
1 => 'Amelia said "I am a camel"'
2 => Amelia said "I am a camel"
3 => "I am a camel"
4 =>
5 =>

没关系。我明白那个。但是,我不想知道这些数字。因此,我将第一个捕获组命名为捕获,然后在 %-中查看,希望看到我先前在 $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领带以便 %-找出来,但随后我必须找出如何做到这一点。

最佳答案

在解决了这个问题之后,我很满意我在问题中所说的是正确的。每次对(?PARNO)的调用都会获得一组完整且独立的匹配变量集,并在运行结束时将其丢弃。

您可以通过使用模式匹配运算符外部的数组并在重复的子模式的末尾将其压入该子模式,来获得每个子模式中所有匹配的内容,例如本例:

#!/usr/bin/perl
# nested_carat_n.pl

use v5.10;

$_ =<<'HERE';
Outside "Top Level 'Middle Level "Bottom Level" Middle' Outside"
HERE

my @matches;

say "Matched!" if m/
(?(DEFINE)
(?<QUOTE_MARK> ['"])
(?<NOT_QUOTE_MARK> [^'"])
)
(
(?<quote>(?&QUOTE_MARK))
(?:
(?&NOT_QUOTE_MARK)++
|
(?R)
)*
\g{quote}
)
(?{ push @matches, $^N })
/x;

say join "\n", @matches;

我在 Chapter 2 of Mastering Perl中进行了深入研究,您可以免费阅读(至少一段时间)。

关于regex - 完成后,Perl的 `(?PARNO)`是否会丢弃其自己的命名捕获?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19123377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com