#!/usr/bin/perl -w use strict; my $input = "(abdc)(adc-b)"; my @expr; while ($input =~ s!\(([-a-z,]+)\)!!) { my @items = split '', $1; my (@and, @or) = (); while (@items) { my $elem = shift @items; if ($elem eq '-') { push @or, shift @items; } else { push @and, $elem; } } push @expr, [ \@and, \@or ]; } my $first = shift @expr; my @output = @{ @$first[0] }; while (my $next = shift @expr) { my (%keep, %drop); @keep{@{ @$next[0] }} = (); @drop{@{ @$next[1] }} = (); foreach (@output) { next if (exists $keep{$_}); $_ = undef if (exists $drop{$_}); } } my $output = join('', grep{ defined($_) } @output); print "Result is; $output\n";