my %cache = ('-1' => qr/([^\(\)]+)\)+\Z/); sub peel { my $str = shift; my $level = shift || 0; if (!exists $cache{$level}) { my $opening = '[^\(]+\(' x $level; my $closing = '\)' x $level; $cache{$level} = qr/\A$opening(.+?)$closing\Z/; } $str =~ $cache{$level}; return $1; }