grep - 正则表达式多条件选择

问题描述 投票:0回答:1

给定一个包含此字符串的文件:

IT1*1*EA*VN*ABC@SAC*X*500@REF*ZZ*OK@IT1*1*CS*VN*ABC@SAC*X*500@REF*ZZ*BAR@IT1*1*EA*VN*ABC@SAC*X*500@REF*ZZ*BAR@IT1*1*EA*VN*ABC@SAC*X*500@REF*ZZ*OK@

目标是提取以下内容:

IT1*1*EA*VN*ABC@SAC*X*500@REF*ZZ*BAR@

标准是:

  1. IT1“行”必须包含
    *EA*
  2. REF 行必须包含
    BAR

一些需要考虑的注意事项:

  • “@”可以被认为是换行符
  • “组”行包含以 IT1 开头并以 REF 结尾的行
  • 我正在运行 GNU grep 3.7。

目标是选择符合标准的“组”线路。

我尝试了以下方法:

grep -oP "IT1[^@]*EA[^@]*@.*REF[^@]*BAR[^@]*@" file.txt

但它从示例的开头捕获字符。

还尝试使用lookarounds:

grep -oP "(?<=IT1[^@]*EA[^@]*@).*?(?=REF[^@]*BAR[^@]*@)" file.txt

但是我的 grep 版本返回:

grep:lookbehind 断言不是固定长度

regex linux grep gnu pcre
1个回答
0
投票

您的问题是

.*
将从第一个
IT1
到最后一个
REF
的字符与
BAR
匹配。您需要确保匹配不会超过下一个
IT1
,您可以通过将
.*
替换为 tempered 贪婪标记
(?:(?!@IT1).)*
:

来实现这一点
IT1[^@]*EA[^@]*@(?:(?!@IT1).)*REF[^@]*BAR[^@]*@

这只会匹配

IT1
与其对应的
REF

regex101 上的正则表达式演示

© www.soinside.com 2019 - 2024. All rights reserved.