2011-04-08 16 views
11

Hasta ahora, si quería agrupar varios de expresiones regulares dentro como if, lo hice de esta manera:Perl expresiones regulares en una sentencia if [Sintaxis]

my $data =... 
if ($data =~ m/regex/ && $data =~ m/secondregex/) {...} 

¿Hay un acceso directo (y yo' Estoy seguro de que hay, es Perl!) para evitar la repetición de $ datos, algo así como:

if ($data =~ m/regex/ && m/secondregex/) {..} 

??

Gracias,

+1

¿Puede dar un ejemplo ¿patrón? Debería poder combinar ambos patrones en uno. – halfdan

+0

¿Por qué necesita dos expresiones regulares? Si se prueba con && Apuesto a que puede ser una sola expresión.[edit] Oh, soy tarde :) +1 halfdan – tmg

+3

Si los combinaste en una sola expresión regular necesitarías combinar todas las órdenes posibles en las que los subpatrones pueden aparecer en una sola cadena, generando expresiones regulares aún más complejas para contrastar . Para dos expresiones regulares sería 'm /^(?:.* regex. * Secondregex. *) | (?:. * Secondregex. * Regex. *) $ /' Durante tres o más, se pone feo. – BoltClock

Respuesta

17

utilizar la variable por defecto $_ como esto:

$_ = $data; 
if (m/regex/ && m/secondregex/) {..} 

como expresiones regulares actúan sobre $_ por defecto (como muchas otras cosas en Perl).

Solo asegúrese de que no se encuentre en un bloque donde $ _ se rellene automáticamente y tendrá que usarlo más adelante en este bloque. Una vez que se sobrescribe, se va.

+10

Es posible que desee localizar '$ _':' local $ _ = $ data' –

+0

¡Solución dulce! Gracias – snoofkin

+0

Asignar a una variable implícita me parece un truco. – BillMan

14
for ($data) { 
    if (/regex/ && /secondregex/) {...} 
} 
+4

Esto me parece más limpio que asignar explícitamente un $ _ localizado - es análogo a "con" y construcciones similares en otros idiomas. –

0

Según su estructura de condiciones if. También puede refactorizar algunas de las expresiones regulares utilizando if anidados.

es decir: cambiar

if (/regex1/ && /regex2/) block1 
elsif (/regex2/ && /regex3/) block2 

en

if (/regex2/){ 
    if (/regex1/) block1 
    else (/regex3/) block2 
} 
2

Uno más sugerencia. Dependiendo de cuánto tiempo deba coincidir su lista de expresiones regulares en una si, y con qué frecuencia debe hacer esta tarea amable, tendría mucho sentido convertirla en una subrutina.

Inspirado por el rubí de cada:

sub matchesAll ([email protected]) { 
    my $string = shift; 
    my $result = 1; 
    foreach $_ (@_) { 
    $result &&= $string =~ $_; 
    } 
    $result; 
} 

y luego hacer

if (matchesAll $data, $regex1, $regex2, $regex3, $regex4) ... 

Nota: esto requiere que todos los regexs compilarse para su uso futuro usando QR // $regex1 = qr/regex1/

2

a añadir a la lista de formas de poner $data en $_:

if (grep { m/regex/ && m/secondregex/ } $data) {...} 
6

Sólo una línea utilizando partido inteligente:

use 5.010; 
if ($data ~~ [qr/regex1/,qr/regex2/]) { ... } 
0

La forma correcta para cambiar

if (/re1/ && /re2/ && /re3/) { ... } 

en un único patrón es de esta manera:

if (/(?=.*re1)(?=.*re2)(?=.*re3)/s) { ... } 
Cuestiones relacionadas