use strict; use warnings; use List::Util 'max'; srand; my @lines = ; my $n = 1000; my $long = ''; $long .= qw{( )}[ int(rand() * 2) ] for 1 .. $n; my $regex = qr{ ( # start of capture group 1 \( # match an opening parenthesis (?: [^()]++ # one or more non-parentheses, non backtracking | # OR (?1) # recurse to capture group 1 )* \) # match a closing parenthesis ) # end of capture group 1 }x; for my $string (@lines, $long) { my $max = 0; my $occ = 1; my @groups = $string =~ m/$regex/g; if (@groups) { @groups = sort { length $a <=> length $b } @groups; $max = length $groups[-1]; for my $i (reverse 0 .. $#groups - 1) { if (length $groups[$i] == length $groups[-1]) { ++$occ; } else { last; } } } print "$max $occ\n"; } __DATA__ )((())))(()()) ))( ()(())() ((((()((( (()())()(())()()())())()((()(()(())()()())((()(())()(()()()()))()(())()(((()())()(()((())()(())(()))