Kcoder
Kcoder

Reputation: 3480

How do you match a string with nested brackets among other bracketed strings?

I have a log file that I'm try to pull a specific section from:

[2020][159]Debugging: [FIXED_RANDOM_324 - Some Text[R] Here[TM]][PRODUCTION1] - [192.0.0.1] - [Mozilla]
[2021][532]Debugging: [FIXED_ABCDEF_21 - Simple][PRODUCTION2] - [192.0.0.32] - [Chrome]

I need to get FIXED_RANDOM_324 - Some Text[R] Here[TM] and FIXED_ABCDEF_21 - Simple

The "FIXED_" part will always be the same.

I tried using something simple like \[FIXED.*]\] but that only worked on the top line.

Upvotes: 1

Views: 63

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186698

You can try @"FIXED.*?(?=\]\[)" pattern:

 FIXED  - fixed part
 .*?    - zero or more arbitrary characters (as few as posible)
 ][     - followed by ][ (but not included into the match) 

Demo:

  string[] tests = new string[] {
    "[2020][159]Debugging: [FIXED_RANDOM_324 - Some Text[R] Here[TM]][PRODUCTION1] - [192.0.0.1] - [Mozilla]",
    "[2021][532]Debugging: [FIXED_ABCDEF_21 - Simple][PRODUCTION2] - [192.0.0.32] - [Chrome]",
  };

  Regex regex = new Regex(@"FIXED.*?(?=\]\[)");

  var result = tests
    .Select(test => regex.Match(test))
    .Where(match => match.Success)
    .Select(match => match.Value);

  Console.Write(string.Join(Environment.NewLine, result));

Outcome:

FIXED_RANDOM_324 - Some Text[R] Here[TM]
FIXED_ABCDEF_21 - Simple

Edit: In case we want to count opening and closing brackets we have to use a more elaborated pattern, e.g.

 @"FIXED(?:.*?(?<o>\[)?.*?(?<-o>\])?.*?)*(?=\])"

here (?<o>\[) and (?<-o>\]) are balancing groups to match opening and corresponding closing brackets:

  string[] tests = new string[] {
    "[2020][159]Debugging: [FIXED_RANDOM_324 - Some Text[R] Here[TM]][PRODUCTION1] - [192.0.0.1] - [Mozilla]",
    "[2021][532]Debugging: [FIXED_ABCDEF_21 - Simple][PRODUCTION2] - [192.0.0.32] - [Chrome]",
    "[2021][532]Debugging: [FIXED_XYZ_02 - [Some][Text]][PRODUCTION2] - [192.0.0.32] - [Chrome]",
    "[2021][532]Debugging: [FIXED_XYZ_02 - [Some][Text] more][PRODUCTION2] - [192.0.0.32] - [Chrome]",
  };

  Regex regex = new Regex(@"FIXED(?:.*?(?<o>\[)?.*?(?<-o>\])?.*?)*(?=\])");

  var result = tests
    .Select(test => regex.Match(test))
    .Where(match => match.Success)
    .Select(match => match.Value);

  Console.Write(string.Join(Environment.NewLine, result));

Outcome:

FIXED_RANDOM_324 - Some Text[R] Here[TM]
FIXED_ABCDEF_21 - Simple
FIXED_XYZ_02 - [Some][Text]
FIXED_XYZ_02 - [Some][Text] more

Upvotes: 3

Related Questions