2012-06-11 17 views
5

Quiero hacer coincidir dos cadenas diferentes y la salida debe venir en $ 1 y $ 2, De acuerdo conmigo en este ejemplo, si $ a es 'xy abc', entonces $ 1 debe ser 'xy abc' y $ 2 debería 'abc', pero la parte 'abc' viene en $ 3. ¿Puede ayudarme a escribir una expresión regular en que $ 1 debe tener una cadena completa y $ 2 si tiene una segunda parte? Estoy usando Perl 5.8.5.perl regex matching failed

my @data=('abc xy','xy abc'); 
foreach my $a (@data) { 
    print "\nPattern= $a\n"; 
    if($a=~/(abc (xy)|xy (abc))/) { 
     print "\nMatch: \$1>$1< \$2>$2< \$3>$3<\n"; 
    } 
} 

Salida:

perl test_reg.pl 

Pattern= abc xy 

Match: $1>abc xy< $2>xy< $3>< 

Pattern= xy abc 

Match: $1>xy abc< $2>< $3>abc< 
+1

"Estoy usando Perl 5.8.5." Eso es ocho años. Realmente deberías considerar actualizar. –

Respuesta

1

Debido a que sólo una de las capturas $2 y $3 puede ser definido, puede escribir

foreach my $item (@data) { 

    print "\nPattern= $item\n"; 

    if ($item=~/(abc (xy)|xy (abc))/) { 
    printf "Match: whole>%s< part>%s<\n", $1, $2 || $3; 
    } 
} 

que da la salida

Pattern= abc xy 
Match: whole>abc xy< part>xy< 

Pattern= xy abc 
Match: whole>xy abc< part>abc< 
4

se puede hacer con:

(?|(abc (xy))|(xy (abc))) 

por qué se molestó con la captura de todo el asunto? Puedes usar $& para eso.

my @data = ('abc xy', 'xy abc'); 
for(@data) { 
    print "String: '$_'\n"; 

    if(/(?|abc (xy)|xy (abc))/) { 
     print "Match: \$&='$&', \$1='$1'\n"; 
    } 
} 
+0

''? | '' ¿Qué es eso? – Cylian

+0

@Cylian, citado de 'perlre': *" Este es el patrón de "reinicio de bifurcación", que tiene la propiedad especial de que los grupos de captura se numeran desde el mismo punto de partida en cada rama de alternancia. "* – Qtax

+0

+1, Al principio parece un error! ¡Pero nada más que mi ignorancia! – Cylian

0

Si se puede vivir con lo que permite más variables de captura que $1 y $2, luego use las subcadenas de la rama de la alternativa que coincida.

for ('abc xy', 'xy abc') { 
    print "[$_]:\n"; 

    if (/(abc (xy))|(xy (abc))/) { 
    print " - match: ", defined $1 ? "1: [$1], 2: [$2]\n" 
            : "1: [$3], 2: [$4]\n"; 
    } 
    else { 
    print " - no match\n"; 
    } 
} 

Salida:

[abc xy]: 
    - match: 1: [abc xy], 2: [xy] 
[xy abc]: 
    - match: 1: [xy abc], 2: [abc]