Search code examples
regexregex-group

Regex Help - group within a group one or more times


I am looking for some help. I am unsure if it is possible to match an outside group and also match inside the group if exists.

for example:

10/22/2021 8:56:35 test Warning ID: 111 OD: 00:00:01 blah blah blah blah

I want to

  • group date: 10/22/2022
  • group time: 8:56:35
  • group proc: test
  • group log_level: Warning
  • group ID(if exist): ID: 111
  • group message: test Warning ID: 111 OD: 00:00:01 blah blah blah blah

Regex appears to almost work but fails if ID is not present. I only want to capture ID if we match, else just capture the message.

^(?<date>(?:\d+)\/\d+\/\d+)\s+(?<time>(?:\d+:){2}\d+)\s+(?<proc>\w+)\s(?<log_level>\w+)\s(?<message>.*(?:ID: (?<ID>\d+)).*)$

I want to match the ID group 0 or 1 times (?) but when i add ? to the group it breaks the regex for the message group. ie:

^(?<date>(?:\d+)\/\d+\/\d+)\s+(?<time>(?:\d+:){2}\d+)\s+(?<proc>\w+)\s(?<log_level>\w+)\s(?<message>.*(?:ID: (?<ID>\d+))?.*)$

Any help would be greatly appreciated


Solution

  • You can use

    ^(?<date>(?:\d+)\/\d+\/\d+)\s+(?<time>(?:\d+:){2}\d+)\s+(?<proc>\w+)\s(?<log_level>\w+)\s(?<message>.*?(?:ID: (?<ID>\d+).*)?)$
    

    See the regex demo.

    The only change is in Group "message" pattern, that now looks like (?<message>.*?(?:ID: (?<ID>\d+).*)?). It matches

    • .*? - any zero or more chars other than line break chars as few as possible
    • (?:ID: (?<ID>\d+).*)? - an optional non-capturing group that matches
      • ID: - a fixed string
      • (?<ID>\d+) - Group "ID": one or more digits
      • .* - any zero or more chars other than line break chars as many as possible.