Using RegEx to balance match parenthesis

Regular Expressions can definitely do balanced parentheses matching. It can be tricky, and requires a couple of the more advanced Regex features, but it’s not too hard.

Example:

var r = new Regex(@"
    func([a-zA-Z_][a-zA-Z0-9_]*) # The func name

    \(                      # First '('
        (?:                 
        [^()]               # Match all non-braces
        |
        (?<open> \( )       # Match '(', and capture into 'open'
        |
        (?<-open> \) )      # Match ')', and delete the 'open' capture
        )+
        (?(open)(?!))       # Fails if 'open' stack isn't empty!

    \)                      # Last ')'
", RegexOptions.IgnorePatternWhitespace);

Balanced matching groups have a couple of features, but for this example, we’re only using the capture deleting feature. The line (?<-open> \) ) will match a ) and delete the previous “open” capture.

The trickiest line is (?(open)(?!)), so let me explain it. (?(open) is a conditional expression that only matches if there is an “open” capture. (?!) is a negative expression that always fails. Therefore, (?(open)(?!)) says “if there is an open capture, then fail”.

Microsoft’s documentation was pretty helpful too.

Leave a Comment