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

I'm trying to setup a check to see if any of multiple strings exist within a scalar. Essentially if ($string =~ /string1|string2|string3|string4/) I am trying to find a way to figure out what matches occur. For example, if $string contains both string1 and string4 I need to know that both matches occur. My guess is there is a much much better way to handle this. Especially since I can't seem to figure out how to make it work this way. Any suggestions would be appreciated.

Replies are listed 'Best First'.
Re: Silly regex with match extrapolation
by GrandFather (Saint) on Oct 13, 2008 at 23:33 UTC

    Can the multiple matches overlap? How many match strings do you expect? How long do you expect the match strings to be? Are the match strings simple strings, or do they involve regex components? How long do you expect the target string to be? Do you expect there to be multiple matches for an individual match string?


    Perl reduces RSI - it saves typing
      The patterns to match on are simple strings. The being checked will contain the html and txt portions of email messages. There may be multiple matches per scalar being tested. So if I'm testing $scalar for /bob|jan|mike/ $scalar might have any combination of all three and even multiple instances of all three. But, I only need to know about the fist instance of each. Essentially, does $scalar match for each bob jan and mike. Hope that makes sense. Thank you for the help.

        Take a look at Regexp::List. Consider:

        use strict; use warnings; use Regexp::List; my @words = qw!bob fred frederic ann anne annie!; my $target = <<DATA; This list contains Bob, Frederic, Fred, Robert, Annette and Ann. And this list conatins Fred and Frederic. DATA my $match = Regexp::List->new (modifiers => 'i')->list2re (@words); my @matches = $target =~ /($match)/g; print "@matches";

        Prints:

        Bob Frederic Fred Anne Ann Fred Frederic

        Perl reduces RSI - it saves typing
        Probably not very efficient, but just count them:
        use warnings; use strict; my @names = qw(bob jan mike); while (<DATA>) { my $cnt = 0; for my $name (@names) { $cnt++ if /\b$name\b/i; } print if $cnt == 3; } __DATA__ Mike went to the store with Jan. Jan, Bob and Mike ate lunch. In January, we bobbed for apples and sang into a mike.

        Prints:

        Jan, Bob and Mike ate lunch.
Re: Silly regex with match extrapolation
by apomatix (Novice) on Oct 14, 2008 at 18:43 UTC
    Another way, in 1 line:
    @matches = grep {$scalar =~ /$_/} qw/string1 string2 string3 string4/