如何计算 Perl 中命名捕获组的匹配项

How to count matches for a named capture group in Perl

我有一个我拼凑的 Perl 命令,运行是一个在文件上查找和替换的正则表达式。它工作得很好,但不幸的是 "modifying" 文件的副作用,即使生成的文件是相同的。这是有道理的,因为它正在用自己替换比赛。我们不能这样做,因为结果是 make 管道的一部分,并且每次 运行.

时都会导致整个重建

我现在想要 运行 一个命令来获取特定命名捕获组的匹配计数,以便我可以在实际 运行 宁第一个之前测试是否需要替换任何东西命令。

通过 bash 使用一些 bash 变量执行命令:perl -0777 -i -pe '$cnt=0;s{('$PASSTHROUGH'|'$REPLACE')}{$+{PASSTHROUGH}?$+{PASSTHROUGH}:(++$cnt,'$REPLACEMENT')")}peg; END{print "$cnt\n"}'

同样,这很好用并且给出了实际替换的数量,因为 $cnt 仅在三元运算符的 else 分支中递增。如果我要 运行 只匹配 $REPLACE 模式,我不会得到正确的数字,因为它通常会匹配 $PASSTHROUGH 组中的东西。

我怀疑有一种方法可以检索特定组的计数,但我不知道 Perl 或术语,所以我正在努力寻找如何将此命令更改为 [=29] 的答案=]不是做一个替换,而是简单地计算与$REPLACE子模式的匹配。这是一个命名组:(?<REPLACE>some-regex-pattern)

问题更新后编辑

  • -0777表示整个文件被读取一次(输入记录分隔符undef)
  • -i:就地编辑文件(如 sed -i),必须删除以避免修改文件
  • -p :打印行

以下命令应该只打印匹配项的数量

perl -0777 -ne '$cnt=@a=m{('$PASSTHROUGH'(*SKIP)(?!)|'$REPLACE')}pg;print "$cnt\n"'

它的做法不同:

  • pattern alternation的原则是先匹配不匹配的,不匹配的保留我们想要的
  • (*SKIP) : 是一个回溯控制动词,防止正则表达式引擎在匹配失败后回溯,这就是通常所做的
  • (?!) : 与 (*FAIL)
  • 相同