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

This is the obvious way to check if $string matches any regex in @regex:
@regex = ( 'foo' 'b[a-z]' ); $string = 'foo'; my $matched = 0; foreach $test ( @regex ) { $matched++ if ($string =~ m/$test/); } if ($matched) { ...
There must be a shorter, simpler way. Can you think of one? The reverse, matching a single regex against an array of strings, is simply:
if ( grep($regex, @strings) { ...
But here we need to do the opposite, matching one string to many regexes (to see if ANY match). I'm thinking map() may come to the rescue, but I'm not in the habit of using it, so I'm missing something. I tried:
if ( map(string =~ /$_/, @regex) ) { ...
Ray B. Morris support@webmastersguide.com

Replies are listed 'Best First'.
Re: Matching an array of regexes (grep in reverse)
by ccn (Vicar) on Nov 20, 2008 at 20:07 UTC
    grep { $string =~ /$_/ } @regex;

    and if you don't need to count how many matches occured than you can speed up that code:

    if ( grep { $string =~ /$_/ and return 1 } @regex ) { ... }

    Updated: (thx to Anomalous Monk)

    sub is_match { grep { $string =~ /$_/ and return 1 } @regex; } if ( is_match() ) { print qq($string matched some regex); }
      >perl -wMstrict -le "my @regexes = qw( foo b[a-z] ); my $string = 'fooey'; if ( grep { $string =~ /$_/ and return 1 } @regexes ) { print qq($string matched some regex); } " Can't return outside a subroutine at -e line 1. >perl -wMstrict -le "use List::MoreUtils 'any'; my @regexes = qw( foo b[a-z] ); my $string = 'fooey'; if ( any { $string =~ /$_/ } @regexes ) { print qq($string matched some regex); } " fooey matched some regex
      $raymor->banghead('stupid');
      How can I do grep in reverse, I ask. By reversing the arguments in the grep EXPR, of course. I always think of the idiom grep(/regex/, @list), but the prototype is grep(BLOCK, @list) ! Thanks. I'll try to have a better question next time.
      Ray
Re: Matching an array of regexes (grep in reverse)
by moritz (Cardinal) on Nov 20, 2008 at 20:58 UTC
    my $common_re = join '|', @regex; if ($str =~ m/$common_re/) { ... }

      Or Regexp::Assemble

      use Regexp::Assemble; my $re = Regexp::Assemble->new(); $re->add($_) for @regex; if ( $str =~ /$re/ ) { ... }
Re: Matching an array of regexes (grep in reverse)
by jeffa (Bishop) on Nov 20, 2008 at 20:12 UTC

    Hmmmm ... how about a closure? :)

    my @regex = ( 'foo', 'b[a-z]' ); my $string = 'foo'; my $inc = inc(); &$inc( $string, $_ ) for @regex; print &$inc(); sub inc { my $count = 0; return sub { return $count unless @_; $count++ if $_[0] =~ /$_[1]/; }; }

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Matching an array of regexes (grep in reverse)
by gone2015 (Deacon) on Nov 20, 2008 at 20:09 UTC

    Thread 723032 is superficially similar, though there it's many strings beinging bashed against many regex...