$expr = '(A&(B&C)|((C&D)|\((A EQ 1)))'; # 01234567890123456789012345678 my (@open, @close); my @charArr = split //, $expr; foreach my $pos ( 0..$#charArr ) { push @open, $pos if ( $charArr[$pos] =~ /\(/ && $charArr[$pos-1] ne "\\" ) ; push @close, $pos if ( $charArr[$pos] =~ /\)/ && $charArr[$pos-1] ne "\\" ) ; } die "Imbalance Pair" unless @open == @close; print "@open$/@close$/$/"; my @preced; foreach my $firstClose ( @close ) { my @temp = (); while ( @open ) { my $lastOpen = pop @open; if ( $lastOpen < $firstClose ) { push @preced, "$lastOpen - $firstClose"; @open = (@open, @temp); last } else { unshift @temp, $lastOpen; } } } print $_.$/ foreach @preced; __END__ prints: 0 3 9 10 18 7 14 25 26 27 3 - 7 10 - 14 18 - 25 9 - 26 0 - 27