regex 如何计算文件中的多行重复模式?

rryofs0p  于 2023-04-07  发布在  其他
关注(0)|答案(4)|浏览(95)

我有一个文件,它有以下模式。

A
.
.
XYZ
.
.
A
.
.
A
.
.
A
.
.
XYZ

其中“.”是带有随机单词(不是A或XYZ)的新行。
我想统计所有匹配的模式

A
.  (any number of lines)
XYZ

我还想只在A后面跟着XYZ的情况下计算它,而不是在A后面跟着另一个A的情况下。
我尽力了

pcregrep -Mc 'A.*(\n?|.)*?XYZ' file.txt

但它失败了

> pcregrep: pcre_exec() gave error -27 while matching text that starts:

上述输入的期望输出:2
有人知道怎么做吗?

w46czmvw

w46czmvw1#

您可以使用非贪婪量词来匹配最接近的A和XYZ对:

pcregrep -Mc '^A$[.\n]*?^XYZ$' file.txt

演示:https://regex101.com/r/ETVkuh/3

8aqjt8rx

8aqjt8rx2#

可以使用perl

perl -ne "/A/../XYZ/ && ($last += 1);END {print $last};" file.txt
2
mrzz3bfm

mrzz3bfm3#

ripgrep

$ rg -UPc '(?s)^A$((?!^A$).)*?^XYZ$' ip.txt
2

-U选项启用多行搜索。-P用于PCRE(因为我们需要查找),-c用于获取计数。(?s)启用.来匹配换行符。((?!^A$).)*?是一个否定组,以防止将A作为整行进行匹配。
如果你不关心行锚点,并且A总是一个字符,你可以简化命令如下:

$ rg -Uc 'A[^A]*?XYZ' ip.txt
2
nbewdwxp

nbewdwxp4#

您可以用途:

/^A$(?:(?!^A$)[\s\S])*?^XYZ$/gm

Demo
最简单的方法是使用Perl:

perl -0777 -nE '$cnt=()=/^A$(?:(?!^A$)[\s\S])*?^XYZ$/gm; say $cnt;' file

或者如果你不想吞下文件,使用范围正则表达式:

perl -nE '/^A$(?:(?!^A$)[\s\S])*?/m../^XYZ$/m && $cnt++; END{say $cnt}' file

或者如果你想变得更迟钝和:

perl -nE '/^A$((?!^A$)[\s\S])*?/m../^XYZ$/m && $cnt++}{ say $cnt' file

相关问题