NS.X.
NS.X.

Reputation: 2142

Regex w/ balancing group that matches not only the outmost matches

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

Answers (2)

Qtax
Qtax

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

vurentjie
vurentjie

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

Related Questions