1

I have a good regex that works well for most my cases:

"\(.*\)"

This regex matches nested brackets which is good: "ABC ( DEF (GHI) JKL ) MNO"

But there is a tricky case: "This is ABC (XXX) DEF (XXX) (XXX)". As you can see this regex matches also DEF, but it doesn't.

Any ideas of how I can adjust my regex?

Vnuuk
  • 6,177
  • 12
  • 40
  • 53

2 Answers2

1

If you don't insist on regular expressions you can put a simple stack-based implementation:

using System.Linq;

...

private static IEnumerable<string> EnumerateEnclosed(string value) {
  if (null == value)
    yield break;

  Stack<int> positions = new Stack<int>();

  for (int i = 0; i < value.Length; ++i) {
    char ch = value[i];

    if (ch == '(')
      positions.Push(i);
    else if (ch == ')') 
      if (positions.Any()) {
        int from = positions.Pop();

        if (!positions.Any()) // <- outmost ")"
          yield return value.Substring(from, i - from + 1);
      }
  }
}

Test:

// Let's combine both examples into one and elaborate it a bit further:
string test = "ABC (DEF (GHI) J(RT(123)L)KL) MNO (XXX1) DEF (XXX2) (XXX3)";

Console.WriteLine(string.Join(Environment.NewLine, EnumerateEnclosed(test)));

Outcome:

(DEF (GHI) J(RT(123)L)KL)
(XXX1)
(XXX2)
(XXX3)
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
0

Regex: \([^)]+\)[^(]+\)|\([^)]+\)

Details:

[^(] Match a single character not present in the list "("

+ Matches between one and unlimited times

| or

Regex demo

Srdjan M.
  • 3,310
  • 3
  • 13
  • 34