2011-07-15 11 views
5

Quiero buscar en las líneas de un archivo para ver si alguno de ellos coincide con uno de un conjunto de expresiones regulares.¿Cómo puedo saber qué parte de una expresión regular de Perl se corresponde con una cadena?

algo como esto:

my @regs = (qr/a/, qr/b/, qr/c/); 
foreach my $line (<ARGV>) { 
    foreach my $reg (@regs) { 
     if ($line =~ /$reg/) { 
     printf("matched %s\n", $reg); 
     } 
    } 
} 

pero esto puede ser lento.

Parece que el compilador de expresiones regulares podría ayudar. ¿Hay una optimización de esta manera:

my $master_reg = join("|", @regs); # this is wrong syntax. what's the right way? 
foreach my $line (<ARGV>) { 
    $line =~ /$master_reg/; 
    my $matched = special_function(); 
    printf("matched the %sth reg: %s\n", $matched, $regs[$matched] 
} 

}

donde 'special_function' es la salsa especial que me dice que se ha emparejado parte de la expresión regular.

Respuesta

8

Utilice la captura de paréntesis. La idea básica es el siguiente:

my @matches = $foo =~ /(one)|(two)|(three)/; 
defined $matches[0] 
    and print "Matched 'one'\n"; 
defined $matches[1] 
    and print "Matched 'two'\n"; 
defined $matches[2] 
    and print "Matched 'three'\n"; 
5

Add captura grupos:

"pear" =~ /(a)|(b)|(c)/; 
if (defined $1) { 
    print "Matched a\n"; 
} elsif (defined $2) { 
    print "Matched b\n"; 
} elsif (defined $3) { 
    print "Matched c\n"; 
} else { 
    print "No match\n"; 
} 

Obviamente, en este sencillo ejemplo se podría haber utilizado /(a|b|c)/ igual de bien y acaba de imprimir $1, pero cuando 'a', 'b ', y' c 'pueden ser expresiones arbitrariamente complejas, esto es una victoria.

Si usted está construyendo la expresión regular mediante programación puede que le resulte doloroso tener que utilizar las variables numeradas, así que en lugar de romper el rigor, busque en las @- o @+ matrices lugar, que contienen las compensaciones para cada posición de coincidencia. $-[0] siempre se establece siempre que el patrón coincida, pero $-[$n] superior solo contendrá valores definidos si el grupo de captura n coincide.

Cuestiones relacionadas