【问题标题】:Regex based on presence of attribute and its value基于属性及其值的存在的正则表达式
【发布时间】:2020-05-05 18:06:57
【问题描述】:

我有一个关于正则表达式的问题,这里是我的文字:

1 200 file:test01.txt, action:read, User:dummy
2 201 file:test01.txt, action:write, User:dummy
3 202 file:unknown, keepalive , User:dummy
4 450 file:test01.txt, action:read, User:dummy
5 500 file:test01.txt, action:read, User:dummy
6 201 profiles, action:reload, User:dummy

我想匹配所有行,其中:

  1. 第二列在 20[012]
  2. 动作未读
  3. 动作不存在

所以我会匹配:

2 201 file:test01.txt, action:write, User:dummy
3 202 file:unknown, keepalive , User:dummy
6 201 profiles, action:reload, User:dummy

我正在寻找一种获取行的方法:操作与读取不同以及操作不出现的位置

我尝试了很多方法都没有成功,这是我最后一次失败,第一行幸存下来......

^\d+\s+(?<code>(20[012])).*(action:(?<!read))?

https://regex101.com/r/HGESxR/1

有什么提示吗?

谢谢 马塞洛

【问题讨论】:

  • 因为您说“未读操作”是指“未读操作”,所以我最初认为您的意思是“未执行操作”表示“未执行操作”,但我没有看到你的意思是“行动:”不存在。你需要编辑来解决这个问题。
  • 假设这是你的意图,我建议你说,“action:”,如果存在,后面不跟“read”。

标签: regex pcre regex-group


【解决方案1】:

你可以使用

^\d+\s+(?<code>20[0-2])\s(?:.*action:(?!read)(?<action>\w+)|(?!.*action)).*

见regex demo

详情

  • ^ - 字符串开头
  • \d+ - 1 位以上
  • \s+ - 1+ 个空格
  • (?&lt;code&gt;20[0-2]) - 组“代码”:20,然后是 0、1 或 2
  • \s - 一个空格
  • (?:.*action:(?!read)(?&lt;action&gt;\w+)|(?!.*action)) - 匹配的非捕获组
    • .*action:(?!read)(?&lt;action&gt;\w+) - 除了换行符之外的 0+ 个字符,尽可能多,action: 子字符串,然后是捕获任何 1+ 个单词字符的组“动作”,但不以 read 字符序列开头
    • | - 或
    • (?!.*action) - 紧靠右边,除换行符之外的任何 0+ 字符后都不应有 action,尽可能多
  • .* - 除了换行符之外的 0+ 个字符,尽可能多

【讨论】:

  • 一个小建议:将(?!read) 更改为(?!read\b)。恭喜您最近在您的代表上滚动了两个零!
【解决方案2】:

由于每一行都有一致的模式,您可以使用以下正则表达式。

^(?!.*action:read\b)\d\s+20[012]\s

Demo

正则表达式引擎 (PCRE) 执行以下操作。

^                     match beginning of line
(?!                   begin negative lookahead
  .*action:read\b     match 0+ chars except newline followed by
                      'action:read' followed by a word break
)                     end negative lookahead
\d\s+20               match a digit, 1+ spaces, '20'
[012]                 match '0', '1' or '2'
\s                    match a space

如果您想匹配满足这两个要求的整行(而不是仅仅确定是否满足要求),请将.* 添加到正则表达式的末尾。 Demo

由于固定在行首的负前瞻不消耗任何字符,因此当\d 匹配时,引擎的内部指针位于行首。

【讨论】:

  • 我被否决票弄糊涂了,因为我以为我已经回答了这个问题,即如何匹配具有某些属性的行。我现在从 OPs 代码和@Wiktor 的回答中看到,OP 显然还想在命名捕获组中捕获两个值。如果说明了这个要求,我会做出不同的回答。当然,投反对票的人可能发现我的答案可能有问题,而不是因为没有捕获组。如果读者发现问题,我将不胜感激。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-11
  • 1970-01-01
  • 2016-09-09
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 2011-07-28
相关资源
最近更新 更多