How to check if multiple patterns match in Perl

Is there a way to avoid using this for multiple pattern checks?

Can I break all the patterns in the array and check if it matches any pattern in the patterns array? Please consider the case when I have more than 20 lines of templates.

if(  ($_=~ /.*\.so$/)
  || ($_=~ /.*_mdb\.v$/)
  || ($_=~ /.*daidir/)
  || ($_=~ /\.__solver_cache__/)
  || ($_=~ /csrc/)
  || ($_=~ /csrc\.vmc/)
  || ($_=~ /gensimv/)
){
  ...
}
+5
source share
3 answers

If you can use Perl version 5.10, then there is a really easy way to do this. Just use the new smart match statement (~~) .

use warnings;
use strict;
use 5.10.1;

my @matches = (
  qr/.*\.so$/,
  qr/.*_mdb\.v$/,
  qr/.*daidir/,
  qr/\.__solver_cache__/,
  qr/csrc/,
  qr/csrc\.vmc/,
  qr/gensimv/,
);

if( $_ ~~ @matches ){
  ...
}

If you cannot use Perl 5.10, I would use List :: MoreUtils :: any .

use warnings;
use strict;
use List::MoreUtils qw'any';

my @matches = (
  # same as above
);

my $test = $_; # copy to a named variable

if( any { $test =~ $_ } @matches ){
  ...
}
+11
source

pre-Perl 5.10 - Regexp:: Assemble, , .

+4

Your original code could be written more beautifully:

if(  /.*\.so$/
  || /.*_mdb\.v$/
  || /.*daidir/
  || /\.__solver_cache__/
  || /csrc/
  || /csrc\.vmc/
  || /gensimv/
) { ... }

This is because it $_ =~ /foo/matches with /foo/. If you have Perl 5.10 or higher, I would do as Brad suggested and use the smart match operator.

+1
source

All Articles