regex - 有没有办法计算 Perl 正则表达式匹配的次数?

标签 regex perl

我一直在研究 perldoc perlre 以及 Regular Expressions Cookbook和 Stack Overflow 上的相关问题,我似乎无法找到一个看起来非常有用的表达式:我如何知道当前匹配的数量?

有最后一个封闭组比赛的表达式( $^N ),比赛 3 的内容( \g{3} 如果我理解文档正确的话), $' , $&$` .但似乎没有一个我可以使用的变量只是告诉我当前匹配的数量是多少。

真的不见了吗?如果是这样,是否有任何解释的技术原因为什么它很难实现,或者我只是没有足够仔细地阅读 perldoc?

请注意,我对内置变量感兴趣,而不是像使用 (${$count++}) 这样的解决方法。 .

对于上下文,我正在尝试构建一个仅匹配某些匹配实例的正则表达式(例如匹配所有出现的字符“E”但不匹配出现的 3、7 和 10,其中 3、7 和 10 只是数字在数组中)。我在试图为 this SO question 构建一个更惯用的答案时遇到了这个问题。 .

我想避免将正则表达式评估为字符串以实际将 3、7 和 10 插入正则表达式本身。

最佳答案

我玩了一会儿。同样,我知道这不是您真正要寻找的,但我认为这不是您想要的方式。

我有两个想法。首先,用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在代码断言中工作。它可能会,但是我必须弄清楚如何使用其中一个来使匹配失败,这实际上意味着它必须跳过可能匹配的位。这看起来真的很复杂,这可能就是 Borodin 强制你用伪代码展示的东西。

关于regex - 有没有办法计算 Perl 正则表达式匹配的次数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11915862/

相关文章:

python - 正则表达式在 python 模拟器中有效,但在 perl 中无效

json - 如何在 Perl 中将简单的哈希转换为 json?

perl - 无法在 PERL 中将字符串转换为十六进制

perl - 从 Template Toolkit 中的代码引用调用

macos - 在 Mac 上安装 Perl 模块 WWW::Mechanize

javascript - 是否可以使用 Javascript 循环遍历 RegEx 范围

javascript - 正则表达式打破标记而不是字符串

python - 提取管道和日文字符之间的字母,并用逗号替换空格

javascript - 正则表达式 - 在末尾匹配字符而不使用 $ 符号

perl - 从 `>` 切换到 `<` 毁了我的单线