Processing log file using Regex

Viewed 39

I'm trying to match multiple log entries per line. Every entry is in proceeding format:

instance      Role      id          [state] [flags] [activity]     [status]
-------------------------------------------------------------------------
30:9876543210 Secondary 1122334455           V       InTransition
10:0123456789 Primary   9874563210  IB       EV                     FDown

Items between square brackets are optional, while others are mandatory, and they are space separated.

Regex that I wrote, doesn't work as intended, there is a particular case, that I discovered so far, where match fails.

Current regex: (?<instance>\d+:\d+) (?<role>[a-zA-Z]+) (?<id>\d+)\s?(?<state>SB|IB|RD|DD)?\s?(?<flags>[A-Z]+)?\s(?<activity>InTransition|Down|Up)?\s?(?<other>[a-zA-Z]+)?

Entry that fails: 30:9876543210 Secondary 1122334455 IB InTransition

Result Expected Result
instance: 30:9876543210 instance: 30:9876543210
role: Secondary role: Secondary
id: 1122334455 id: 1122334455
state: IB state: IB
flags: I flags:
activity: activity: InTransition
other: nTransition other:

There is probably much better solution than mine, even if you have a slightest clue how to fix regex that I wrote or you have your own, please feel free to comment. Thank you.

Edit: Here is a RegExr link with a few examples.

1 Answers

You can use

(?<instance>\d+:\d+) (?<role>[a-zA-Z]+) (?<service_id>\d+)(?:\s(?<state>SB|IB|RD|DD))?(?:\s(?<flags>[A-Z]+)\b)?(?:\s(?<activity>InTransition|Down|Up))?(?:\s(?<other>[a-zA-Z]+))?

See the regex demo.

There are two important bits here:

  • The parts that are optional should represent optional occurrences of obligatory pattern sequences. Note you have sequences of optional patterns, e.g. \s?(?<flags>[A-Z]+)?. They all can match an empty string before a non-matching pattern and you would still receive a match. When you use (?:\s(?<flags>[A-Z]+))?, you match an optional occurrence of an obligatory (one) whitespace and one or more uppercase ASCII letters
  • The flags part should be matched as a whole word. Hence, it should look like (?:\s(?<flags>[A-Z]+)\b)?.
Related