Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I found this bit of code and got all excited:
sub bool_to_regexp { local($query) = @_; # Sanity check: query must not contain unescaped "/"! $query =~ s|^/|\\/|; $query =~ s|([^\\])/|\\/|g; # boolean expression (or single word) local($not, $join); #local($qrycmd) = "next unless ("; local($qrycmd) = ""; # $query =~ tr/A-Z/a-z/; $query =~ s/\(/ ( /g; # make sure brackets are separate "wor +ds" $query =~ s/\)/ ) /g; $query =~ s/["'`]//g; # quotes don't work (yet?) # for (split(/[+ \t]+/, $query)) { # Splitting on "+" is bad for queries like "C++"! $query =~ s/\+/\\+/g; for (split(/[ \t]+/, $query)) { # for each "word", do ... next if /^$/; if ($_ eq ")") { $qrycmd .= $_; next; } if ($_ eq "(") { $qrycmd .= "$join$_"; $join = ""; nex +t; } if ($_ eq "NOT") { $not = "!"; next; } if ($_ eq "OR") { $join = " || "; next; } if ($_ eq "AND") { $join = " && "; next; } if (/\*/) { s/\*/\\w*/g; } # match word boundaries only if fully alphanumeric # (for queries like "C++") elsif (/^\w+$/) { s/(.*)/\\b\1\\b/; } $qrycmd .= "$join $not/$_/$caseSensitivity"; $join = " && "; # default to AND joins $not = ""; } $qrycmd .= ""; }
What i'd like to do is use the function to have a command which scans through all the lines in a text file and returns the lines that match the boolean condition I've entered as an argument. So using the function above I have:
my $req = bool_to_regexp($ARGV[0]); print "using $req ...\n"; open (FILE, "stuff") || die "$!"; while(<FILE>) { if ($req) { print $_; } } close FILE;
but the if ($req) doesn't work (just prints everything), so I assumed as the $req contains the regexp, I'd need to eval it, like so:
my $req = bool_to_regexp($ARGV[0]); print "using $req ...\n"; open (FILE, "stuff") || die "$!"; while(<FILE>) { eval if ($req) { print $_; } } close FILE;
but I get a syntax error. How do I make it so that doing:

myprog.pl "fish AND (chips OR beans)"

will return the lines in "stuff" with the words "fish" and either "chips" or "beans"?

Many thanks

ps. I know the sub works just fine, its the eval which I think is the problem

Replies are listed 'Best First'.
Re: Boolean search
by MZSanford (Curate) on Aug 22, 2001 at 18:33 UTC
    I managed to get the folowing to work ok ...
    my $req = bool_to_regexp($ARGV[0]); print "using '$req' ...\n"; open (FILE, "stuff") || die "$!"; while(<FILE>) { if (eval($req)) { print $_; } } close FILE;

    ... so ...
        The eval was the right choice, but eval if ($req) runs the code in $req only is it works (which it won't be because it is not run ... vicious cycle)
    can't sleep clowns will eat me
    -- MZSanford
Re: Boolean search
by Masem (Monsignor) on Aug 22, 2001 at 18:45 UTC
    Why not:
    if ( /$req/ ) { #stuff }

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    It's not what you know, but knowing how to find it if you don't know that's important