3

I have this following string :

((1+2)*(4+3))

I would like to get the values exposed with parentheses separately through a Regex. These values must be in a array like string array.

For example :

  • Group 1 : ((1+2)*(4+3))
  • Group 2 : (1+2)
  • Group 3 : (4+3)

I have tried this Regex :

(?<content>\(.+\))

But she don't functional, because she keeps the group 1

You will have solutions that could allow me to manage this recursively?

YTrl
  • 57
  • 6
  • 2
    What if you have 7 levels of nested parentheses? You should parse the expression recursively, regex won't help you do that. – vgru Dec 11 '18 at 14:44
  • Regex are not suited for deserialization of tree expressions – Cid Dec 11 '18 at 14:44
  • Consider using a [LL Parser](https://en.wikipedia.org/wiki/LL_parser) to transform a mathematical operation string as tree to solve it – Cid Dec 11 '18 at 14:48
  • If you know the number of nesting levels (here = 1) you can do it in C# something similar to `\((\([^()]*\)|[^()]+)+\)` since .NET allows you to iterate over captured texts inside a quantified capturing group you'll get the desired results. – revo Dec 11 '18 at 14:57
  • You may use `Regex.Matches(s, @"(?=(\((?>[^()]+|(?)\(|(?<-o>)\))*(?(o)(?!)|)\)))").Cast().Select(x => x.Groups[1].Value)` – Wiktor Stribiżew Dec 11 '18 at 15:11

1 Answers1

1

You may get all overlapping substrings starting with ( and ending with ) and having any amount of balanced nested parentheses inside using

var result = Regex.Matches(s, @"(?=(\((?>[^()]+|(?<o>)\(|(?<-o>)\))*(?(o)(?!)|)\)))").Cast<Match>().Select(x => x.Groups[1].Value);

See the regex demo online.

Regex details

The regex is a positive lookahead ((?=...)) that checks each position within a string and finds a match if its pattern matches. Since the pattern is enclosed with a capturing group ((...)) the value is stored in match.Groups[1] that you may retrieve once the match is found. \((?>[^()]+|(?<o>)\(|(?<-o>)\))*(?(o)(?!)|)\) is a known pattern that matches nested balanced parentheses.

C# demo:

var str = "((1+2)*(4+3))";
var pattern = @"(?=(\((?>[^()]+|(?<o>)\(|(?<-o>)\))*(?(o)(?!)|)\)))"; 
var result = Regex.Matches(str, pattern)
    .Cast<Match>()
    .Select(x => x.Groups[1].Value);
Console.WriteLine(string.Join("\n", result));

Output:

((1+2)*(4+3))
(1+2)
(4+3)
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563