2

Using C# Grouping Constructs in Regular Expressions one can match the content inside nested parentheses as shown by this response. Following code correctly returns (b/(2c)) and (abc) :

st = "Test(b/(2c)) some (abc) test.";
foreach (Match mt in Regex.Matches(st, @"\((?>\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!))\)"))
{
    Console.WriteLine(mt.Value);
}

However, when I change the pattern to @"(?<=/)\((?>\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!))\)" by just adding (?<=/) before the above pattern to get only the parentheses that are preceded by / I expected to get only (2c) but I am getting (2c)) with an extra ). What I'm missing? Note: If my input string is Test(b)/(2c) some (abc) test. then my new pattern correctly returns (2c) only.

Community
  • 1
  • 1
nam
  • 21,967
  • 37
  • 158
  • 332

1 Answers1

3

The * character is greedy, and it will match as much as possible, which is why the second ) character is matched.

To avoid this, you could either change . to [^)] to match all non ) characters:

Regex.Matches(st, @"(?<=\/)\((?>\((?<DEPTH>)|\)(?<=-DEPTH>)|[^)])*(?(DEPTH)(?!))\)")

It would match (2c) - example.


Alternatively, you could just add ? after * in (?<=-DEPTH>)|.)*? so that * is lazy and . will be matched as few times as possible.

Regex.Matches(st, @"(?<=\/)\((?>\((?<DEPTH>)|\)(?<=-DEPTH>)|.)*?(?(DEPTH)(?!))\)")

It would match (2c) as well - example.

Community
  • 1
  • 1
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • 1
    Your both suggestions work. Thank you for explaining your solution a bit - it was the most important part for me. I replaced my pattern with your first solution on other cases where I'm using more complex nested parentheses and it works there as well. – nam Dec 25 '15 at 04:12