我一直在仔细查看perldoc perlre
以及有关Stack Overflow的Regular Expressions Cookbook及相关问题,我似乎无法找到看似非常有用的表达式:我如何知道当前匹配的数量?
最后一次封闭的小组匹配($^N
),匹配3的内容(\g{3}
,如果我正确理解文档),$'
,$&
和$`
。但似乎并不是我可以使用的变量,它只是告诉我当前匹配的数量是多少。
真的不见了吗?如果是这样,是否有任何解释的技术原因,为什么它很难实现,或者我只是不仔细阅读perldoc?
请注意,我对内置变量 NOT 感兴趣,比如使用(${$count++})
。
对于上下文,我尝试构建一个只匹配匹配的某些实例的正则表达式(例如,匹配所有出现的字符" E"但不匹配出现3,7和10其中3,7和10只是数组中的数字)。当我试图为this SO question构建一个更惯用的答案时,我遇到了这个问题。
我想避免将正则表达式作为字符串进行评估,以便将3,7和10插入正则表达式本身。
答案 0 :(得分:6)
我完全忽略了在另一个问题中使用它的实际效用或智慧。
我认为@-
或@+
可能会执行您想要的操作,因为它们保留了编号匹配的偏移量,但看起来正则表达式引擎已经知道最后一个索引将是什么:
use v5.14;
use Data::Printer;
$_ = 'abc123abc345abc765abc987abc123';
my @matches = m/
([0-9]+)
(?{
print 'Matched \$' . $#+ . " group with $^N\n";
say p(@+);
})
.*?
([0-9]+)
(?{
print 'Matched \$' . $#+ . " group with $^N\n";
say p(@+);
})
/x;
say "Matches: @matches";
这给出了将最后一个索引显示为2的字符串,即使它还没有匹配$2
。
Matched \$2 group with 123
[
[0] 6,
[1] 6,
[2] undef
]
Matched \$2 group with 345
[
[0] 12,
[1] 6,
[2] 12
]
Matches: 123 345
请注意,第一次,$+[2]
是undef,因此还没有填写。你可能能够做到这一点,但我认为这可能会脱离你的问题的精神。如果你真的很喜欢,我猜你可以创建一个绑定标量,它具有@+
中最后一个定义索引的值。
答案 1 :(得分:5)
我玩了一下这个。同样,我知道这不是你想要的,但我认为不存在你想要的方式。
我有两个想法。首先,使用split使用分隔符保留模式,可以将间隙位作为输出列表中的奇数元素。使用split中的列表,您可以计算自己所处的匹配情况,并将其重新组合在一起:
use v5.14;
$_ = 'ab1cdef2gh3ij4k5lmn6op7qr8stu9vw10xyz';
my @bits = split /(\d+)/; # separator retention mode
my @skips = qw(3 7 10);
my $s;
while( my( $index, $value ) = each @bits ) {
# shift indices to match number ( index = 2 n - 1 )
if( $index % 2 and ! ( ( $index + 1 )/2 ~~ @skips ) ) {
$s .= '^';
}
else {
$s .= $value;
}
}
我明白了:
ab^cdef^gh3ij^k^lmn^op7qr^stu^vw10xyz
在我想到第二个想法之前,我以为我真的很喜欢我的split答案。 state是否在替换中起作用?看起来确实如此:
use v5.14;
$_ = 'ab1cdef2gh3ij4k5lmn6op7qr8stu9vw10xyz';
my @skips = qw(3 7 10);
s/(\d+)/
state $n = 0;
$n++;
$n ~~ @skips ? $1 : '$'
/eg;
say;
这给了我:
ab$cdef$gh3ij$k$lmn$op7qr$stu$vw10xyz
我认为你不会比这更简单,即使存在这个神奇的变量。
我有第三个想法,我没有尝试过。我想知道state是否在代码断言中起作用。它可能,但后来我必须弄清楚如何使用其中一个使匹配失败,这实际上意味着它必须跳过可能匹配的位。这看起来非常复杂,这可能是鲍罗丁甚至用伪代码向你施压的原因。