my $q = 'foo and not (bar or beer)'; #user input $q =~ s/(^|[^\\])\//$1\\\//g; #escape slashes my $searchexpr = join ' ', map {s/\/(and|or|not)\/si/$1/gi;$_} map {s/([^\(\)]+)/\/$1\/si/g;$_} split /\s+/, $q; $searchexpr =~ s/\/si (not )?\//\/si and $1\//g; # $searchexpr now is: /foo/si and not (/bar/si or /beer/si) my $found = 0; foreach my $d (@files) { open F, $d; my @f = ; $_ = join '', @f; $found++ if eval $searchexpr; close F; } print 'The expression was true in '.$found.' files';