2011-03-02 11 views
5

Czy istnieje sposób, w jaki można uniknąć tego przy wielu sprawdzeniach wzorca?Jak sprawdzić, czy istnieje wiele dopasowań do wzorca w języku Perl

Czy mogę zerwać wszystkie wzorce w tablicy i sprawdzić, czy pasuje do dowolnego wzorca w tablicy wzorów? Rozważmy przypadek, gdy mam więcej niż 20 ciągów wzorów.

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

@Eric okej .. przepraszam, że tego nie zrobiłem. – Arovit

Odpowiedz

11

Jeśli używasz Perla w wersji 5.10, to jest naprawdę łatwy sposób na zrobienie tego. Wystarczy użyć nowego operatora 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){ 
    ... 
} 

Jeśli nie możesz użyć Perla 5.10, wówczas użyłbym 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

Pamiętaj, że smartmatch jest oznaczony jako eksperymentalny i * zostanie * usunięty lub zmieniony bez powiadomienia. (Wygląda na to, że tak się stanie w 5.26.) To ostatnie rozwiązanie powinno być używane bez względu na twoją wersję Perla. – ikegami

4

Kolejny pre-Perl 5.10 opcją jest Regexp::Assemble, która odbędzie listę wzorców i połączyć je w jeden regex, które sprawdzą wszystkich pierwotnych warunków naraz.

+0

Może to być znacznie bardziej efektywne, szczególnie jeśli testowany wzorzec jest oparty na wielu wartościach. Rozpoczęcie dopasowania do wyrażenia regularnego jest dość drogie. – ikegami

1

Twój oryginalny kod mógł być napisany bardziej estetycznie tak:

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

To dlatego $_ =~ /foo/ jest taka sama jak tylko /foo/. Jeśli masz Perla 5.10 lub wyższego, zrobiłbym to, co Brad zasugerował i skorzystał z operatora inteligentnego dopasowania.

Powiązane problemy