Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex, match string ending with ) and ignore any () inbetween [duplicate]

Tags:

c#

regex

I want to select a part of a string, but the problem is that the last character I want to select can have multiple occurrences.

I want to select 'Aggregate(' and end at the matching ')', any () in between can be ignored.

Examples:

string: Substr(Aggregate(SubQuery, SUM, [Model].Remark * [Object].Shortname + 10), 0, 1)
should return: Aggregate(SubQuery, SUM, [Model].Remark * [Object].Shortname + 10)

string: Substr(Aggregate(SubQuery, SUM, [Model].Remark * ([Object].Shortname + 10)), 0, 1)
should return: Aggregate(SubQuery, SUM, [Model].Remark * ([Object].Shortname + 10))

string: Substr(Aggregate(SubQuery, SUM, ([Model].Remark) * ([Object].Shortname + 10) ), 0, 1)
should return: Aggregate(SubQuery, SUM, ([Model].Remark) * ([Object].Shortname + 10) )

Is there a way to solve this with a regular expression? I'm using C#.

like image 726
Jan V Avatar asked Oct 04 '22 07:10

Jan V


2 Answers

This is a little ugly, but you could use something like

Aggregate\(([^()]+|\(.*?\))*\)

It passes all your tests, but it can only match one level of nested parentheses.

like image 86
Joey Avatar answered Oct 07 '22 20:10

Joey


This solution works with any level of nested parenthesis by using .NETs balancing groups:

(?x)              # allow comments and ignore whitespace
Aggregate\(
(?:
  [^()]           # anything but ( and )
| (?<open> \( )   # ( -> open++
| (?<-open> \) )  # ) -> open--
)*
(?(open) (?!) )   # fail if open > 0
\)


I'm not sure how much the input varies but for the string examples in the question something as simple as this would work:

Aggregate\(.*\)(?=,)
like image 28
Qtax Avatar answered Oct 07 '22 20:10

Qtax