You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何统计文件中A后接XYZ的多行匹配模式(排除A后接A)

问题描述

我有一个文件,内容模式如下:

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

其中.代表内容为随机单词(非A或XYZ)的行。我需要统计所有符合以下模式的出现次数:

A
.  (任意行数)
XYZ

要求仅统计A后直接衔接XYZ的情况,A后接另一个A的情况不计入统计。

我尝试执行以下命令:

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

但出现报错:

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

期望输出为2,请问该如何解决?

解决办法

原因分析

报错的-27是PCRE库的递归深度超限错误,因为你写的正则表达式存在冗余匹配逻辑:.*和(\n?|.)*?会重复匹配内容,导致大量回溯,触发PCRE的递归限制。

正确的pcregrep命令

使用多行模式编写精准的正则,确保只匹配A开头、中间不含A/XYZ的行、最终以XYZ结尾的片段:

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

正则解析:

  • A:匹配起始的A行
  • (?:\n(?!A|XYZ).*)*:非捕获组,匹配任意数量的后续行,要求这些行的行首既不是A也不是XYZ(通过负前瞻(?!A|XYZ)判断)
  • \nXYZ:匹配结尾的XYZ行

执行该命令后会输出期望的2。

可选方案:用awk实现(更直观)

如果觉得正则复杂,用awk处理行逻辑更清晰:

awk 'BEGIN{count=0; flag=0}
$0 == "A" { flag=1 }
flag == 1 {
    if ($0 == "XYZ") {
        count++
        flag=0
    } else if ($0 == "A") {
        flag=1  # 遇到新的A,重置跟踪,放弃之前的A
    }
}
END{print count}' file.txt

逻辑说明:

  1. 初始化计数器count和跟踪标志flag
  2. 遇到A时,开启跟踪标志
  3. 处于跟踪状态时:
    • 遇到XYZ则计数器加1,关闭跟踪
    • 遇到新的A则重置跟踪(放弃之前的A,因为A后接A不符合要求)
  4. 最后输出统计结果

内容的提问来源于stack exchange,提问作者Pranav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 12:07:45