[comp.lang.perl] How can I use the ARGV array as /PATTERN/?

isaacs@hpccc.HP.COM (Stan Isaacs) (01/21/90)

Anybody know an easy way to use an array for a pattern in Perl?  That
is, I want to use the @ARGV array as an "or" pattern (as fgrep -f
does) to choose lines from a file that contain any of the parameters.

Thanks..
  -- Stan

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (01/23/90)

In article <12170002@hpccc.HP.COM> isaacs@hpccc.HP.COM (Stan Isaacs) writes:
: Anybody know an easy way to use an array for a pattern in Perl?  That
: is, I want to use the @ARGV array as an "or" pattern (as fgrep -f
: does) to choose lines from a file that contain any of the parameters.

Bob Best wrote an fgrep in perl that turned out to be faster than fgrep
for word lists up to 150 long.  I can't put my hand on a copy offhand, but
the gist of it is this:

@PATTERNS = ('foo','bar','whatever');

$prog = "while (<>) { study;\n";

foreach $pat (@PATTERNS) {
    $prog .= "print if /$pat/;\n";
}

$prog .= "}\n";

eval $prog;

The important thing is the "study", which is useful when you are going to
be searching the same string for many different patterns.  It builds a
linked list of characters, so the searching code can be very smart.  In
fact, if you look for a word like "cookie", perl knows that "k" is probably
the rarest character, and if there's no "k" in the string, it knows it
doesn't even need to look at the string.  If there are some "k"s in
the string, it only has to check those locations.  That's what makes
it so fast.

Note that "study" assumes you're scanning text or programs that have letter
frequencies similar to English or C.

Larry