#! perl -slw use strict; my $reTokenise = qr[\s*(\S+)(?:\s+((?i:and|or)))?]; sub parseExpr { my $expr = shift; my @tokens = $expr =~ m[$reTokenise]g; pop @tokens unless defined $tokens[ $#tokens ]; return '[' . join( '.', @tokens ) . ']'; } while( ) { chomp; warn "Unbalanced parens '$_'" and next unless tr[(][] == tr[)][]; s[ \( ( [^()]+ ) \) ]{ parseExpr( $1 ) }xe while m[[()]]; $_ = parseExpr( $_ ) if m[\s]; print; } __DATA__ ((A or B) (A) or B) ((A) or B) A or B or C and D ( ( this OR that ) AND other ) ( A or ( B and (C or D) ) or (E and F) ) (A or (B or C) or (D and E)) #### c:\test>junk5 Unbalanced parens '((A or B)' at c:\test\junk5.pl line 15, line 1. Unbalanced parens '(A) or B)' at c:\test\junk5.pl line 15, line 2. [[A].or.B] [A.or.B.or.C.and.D] [[this.OR.that].AND.other] [A.or.[B.and.[C.or.D]].or.[E.and.F]] [A.or.[B.or.C].or.[D.and.E]]