$_ = '(($a $a hi) $a ($a) $a) $a ($a) $a '; my $re; ($re=$_) =~ s/((\()|(\))|.)/${['(','']}[!$2]\Q$1\E${[')','']}[!$3]/gs; $re = join'|',map{quotemeta}eval{/$re/}; die $@ if $@ =~ /unmatched/; s/($re)|\$a/$1?$1:'$b'/eg;