my $textInner = '(outer(inner(most "this (shouldn\'t match)" inner)))'; my $innerRe; $innerRe = qr/ # \( # Start with '(', ( # Start capture (?>[^()]+) # Non-parenthesis | (?> "[^"]*")+ # !!! don't work... | (??{ $innerRe }) # Or a balanced () block ) # One time only, aka the inner one \) # Ending with ')' /x; # $textInner =~ /$innerRe/gs; print "inner: $1\n"; __END__ inner: shouldn't match