2011-03-02 18 views
5

¿Hay alguna manera de evitar el uso de esta opción para múltiples controles de patrones?Cómo verificar la coincidencia de patrones múltiples en Perl

¿Puedo desglosar todos los patrones en una matriz y verificar si coincide con cualquier patrón en la matriz de patrones? Considere el caso cuando tengo más de 20 cadenas de patrones.

if( ($_=~ /.*\.so$/) 
    || ($_=~ /.*_mdb\.v$/) 
    || ($_=~ /.*daidir/) 
    || ($_=~ /\.__solver_cache__/) 
    || ($_=~ /csrc/) 
    || ($_=~ /csrc\.vmc/) 
    || ($_=~ /gensimv/) 
){ 
    ... 
} 
+0

@Eric okay ... lo siento por no haber hecho eso – Arovit

Respuesta

11

Si puede usar la versión 5.10 de Perl, entonces hay una manera realmente fácil de hacerlo. Simplemente use el nuevo operador smart match (~~).

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){ 
    ... 
} 

Si no puede utilizar Perl 5.10, a continuación, me gustaría utilizar 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){ 
    ... 
} 
+1

Tenga en cuenta que smartmatch ahora se marca como experimental y * será * eliminado o cambiado sin previo aviso. (Parece que esto sucederá en 5.26.) La última solución debe usarse independientemente de su versión de Perl. – ikegami

4

Otra opción pre-Perl 5.10 es Regexp::Assemble, que tendrá una lista de patrones y combinarlos en una sola expresión regular que pondrá a prueba todas las condiciones originales a la vez.

+0

Esto puede ser mucho más eficiente, especialmente si el patrón se prueba contra varios valores. Comenzar un partido de expresiones regulares es bastante caro. – ikegami

1

Su código original podría haber sido escrito más bien como esto:

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

Eso se debe a que $_ =~ /foo/ es lo mismo que simplemente /foo/. Si tiene Perl 5.10 o superior, haré lo que sugirió Brad y usaré el operador de coincidencia inteligente.

Cuestiones relacionadas