use strict; use warnings; no warnings qw /uninitialized/; my $re = qr{\A \( (?: (?> [^()]+ ) # Non-parens without backtracking | (??{ $re }) # Group with matching parens )* \) }x; while () { chomp; print "$_: "; print $& if /$re/; print "\n"; } __DATA__ (*********) (***(*)***) ((***)) (((***))) ((**)**(**)) (((())))