Reputation: 2142
I've read multiple sources on how to use balancing group, but all the examples are only matching the outmost matches. Is it possible to match all substrings that match the pattern with one RegEx? (Platform is .NET 4.0)
Here is an example of what I want: Input:
a + ((b + (c + d)) + (e + f))
Desired matches (the 'textbook' RegEx only generates the first match):
- ((b + (c + d)) + (e + f))
- (b + (c + d))
- (c + d)
- (e + f)
Upvotes: 2
Views: 207
Reputation: 33908
This can be done with regex with help of a lookahead. But that isn't optimal as it would "reparse" some groups of parenthesis for every match. Using a real parser would read/parse the string only once, and would be more efficient.
Example (ideone):
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
var re = @"(?x) # ignore spaces and comments
(?= # lookahead (zero width)
(
\( # first (
(?:
(?<open> \( )* # open++
[^()]+
(?<-open> \) )* # open--
)+
\) # last )
(?(open)(?!)) # fail if unblanaced: open > 0
)
)
\( # eat a (, to advance the match a char";
var str = "a + ((b + (c + d)) + (e + f)) + (x + ((y) + (z)) + x)";
var m = Regex.Matches(str, re);
Console.WriteLine("Matched: ");
foreach (Match i in m)
Console.WriteLine(i.Groups[1]);
}
}
Output:
Matched:
((b + (c + d)) + (e + f))
(b + (c + d))
(c + d)
(e + f)
(x + ((y) + (z)) + x)
((y) + (z))
(y)
(z)
Upvotes: 2
Reputation: 106
if you are using javascript,heres an example that does work with the above input,
var rgx = /\([a-z]+\s*\+\s*(\([a-z]+\s*\+\s*[a-z]+\s*\))\s*\)/g;
var str = 'a + (b + (c + d))';
console.log(rgx.exec(str));
it wouldn't work with something more variable like this because it is just a simple test case
a + (d + (c + e) + x)
Upvotes: 0