【发布时间】:2018-01-12 16:21:44
【问题描述】:
我有一个拼凑在一起的 Perl 命令,它在文件上运行正则表达式查找和替换。它工作得很好,但即使生成的文件相同,也会有“修改”文件的不幸副作用。这是有道理的,因为它正在用自己替换匹配项。我们不能这样做,因为结果是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 或术语,所以我正在努力寻找如何将这个命令更改为 not 进行替换,而是仅将匹配项计数到 $REPLACE 子模式。它是一个命名组:(?<REPLACE>some-regex-pattern)
【问题讨论】:
-
我不确定你想用直通做什么,它匹配但没有改变任何东西?那为什么还要匹配呢?如果正确,您只需删除左侧的 PASSTHROUGH 并使用 s{SEARCH}{REPLACE} 的返回值
-
每次正则表达式匹配时都会重置特殊映射 %+,因此除了使用
++$cnt之外没有其他方法可以获取计数,也许可以使用\K来避免替换直通匹配,例如 @987654332 @ -
@Eily 因为
$REPLACE会匹配$PASSTHROUGH匹配的内容。$PASSTHROUGH是一个相当复杂的模式,由其他几个子模式组成并使用递归,据我所知,没有它就不可能做我需要的事情。 -
@NahuelFouilleul 我的问题不在于计数本身
++$cnt对我来说工作正常。我需要一种在不实际修改文件的情况下获取$cnt的方法。我会调查\K。谢谢。 -
@BradAllred,在您显示的代码中,我们看不到文件已修改,也许可以删除
-i选项以不修改文件