2012-06-11 6 views
5

Je veux faire correspondre deux chaînes différentes et la sortie devrait venir en $ 1 et $ 2, Selon moi dans cet exemple, si $ a est 'xy abc', alors $ 1 devrait être 'xy abc' et $ 2 devrait 'abc', mais la partie 'abc' vient avec 3 $. Pouvez-vous m'aider s'il vous plaît à écrire une regex en ce que $ 1 devrait avoir la chaîne entière et $ 2 devrait avoir la deuxième partie. J'utilise perl 5.8.5.Perl regex correspondant échoué

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"; 
    } 
} 

Sortie:

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

"J'utilise Perl 5.8.5." C'est huit ans. Vous devriez vraiment envisager de mettre à jour. –

Répondre

1

Parce que l'une des captures $2 et $3 peuvent être définis, vous pouvez écrire

foreach my $item (@data) { 

    print "\nPattern= $item\n"; 

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

qui donne la sortie

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

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

peut se faire avec:

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

Pourquoi même pris la peine avec la capture la chose? Vous pouvez utiliser $& pour cela.

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

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

''? | '' Qu'est-ce que c'est? – Cylian

+0

@Cylian, cité de 'perlre': *" Ceci est le modèle "reset de branche", qui a la propriété spéciale que les groupes de capture sont numérotés du même point de départ dans chaque branche d'alternance. "* – Qtax

+0

+1, Au début cela semble une erreur! Mais rien que mon ignorance! – Cylian

0

Si vous pouvez vivre avec permettant plusieurs variables de capture que $1 et $2, puis utilisez les sous-chaînes de la branche de l'alternative qui correspond.

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"; 
    } 
} 

Sortie:

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