Search code examples
regexpcreregex-group

Regex based on presence of attribute and its value


I've a question about a regex, here my text:

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

I'd like to mach all rows where:

  1. Second column is in 20[012]
  2. action is not read
  3. action is not present

So I would match:

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

I'm looking for a way to get row where: action is different from read and where action doesn't appear

I tried in many ways without success, here my last failure, the first line survives...

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

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

Any hints?

Thanks Marcello


Solution

  • You may use

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

    See the regex demo

    Details

    • ^ - start of string
    • \d+ - 1+ digits
    • \s+ - 1+ whitespaces
    • (?<code>20[0-2]) - Group "code": 20 and then 0, 1 or 2
    • \s - a whitespace
    • (?:.*action:(?!read)(?<action>\w+)|(?!.*action)) - a non-capturing group matching either
      • .*action:(?!read)(?<action>\w+) - 0+ chars other than line break chars, as many as possible, action: substring, then Group "action" capturing any 1+ word chars, but not starting with read char sequence
      • | - or
      • (?!.*action) - immediately to the right, there should be no action after any 0+ chars other than line break chars, as many as possible
    • .* - 0+ chars other than line break chars, as many as possible