web-dev-qa-db-fra.com

Perl Regex - Imprimer la valeur correspondante

Quelle est l'expression rationnelle Perl pour imprimer la valeur correspondante? Par exemple, je veux imprimer 195 de cette chaîne

"2011-04-11 00:39:28,736::[main]::INFO (Main.Java:73) Test.Main::main() Total Successful Transactions = 195".

Comment puis je faire ça? Merci d'avance

23
CrazyCoder

Vous pouvez utiliser des parenthèses dans l'expression régulière pour capturer des sous-chaînes. Les groupes capturés sont stockés dans 1 $, 2 $, etc. Exemple:

while (<>) {
    if (/Total Successful Transactions = (\d+)/) {
        print "$1\n";
    }
}

ou, un peu plus court:

while (<>) {
    print "$1\n" if /Total Successful Transactions = (\d+)/;
}
35
markusk

Je voulais juste recadrer les réponses précédentes un peu différemment; notez que dans ce cas:

$ Perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = 3/;'
1 

... nous obtenons 1 en cours d'impression - comme dans "oui, j'ai une correspondance". Si nous voulons renvoyer la partie de texte correspondante, comme @ markusk l'a souligné, " utilisez des parenthèses en regex pour capturer les sous-chaînes " :

$ Perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/;'
Xy = 3

Cependant, notez que vous pouvez avoir un problème de concaténation de chaînes avec cet idiome, lors de la capture:

$ Perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = 3/ . "\n";' 
1 # OK
$ Perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/ . "\n";' 
1 # NOT OK

... donc probablement mieux de garder les choses séparées dans ce cas:

$ Perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/ ; print "\n";'
Xy = 3 # OK again

Cependant, si nous voulons capturer "quelque chose", disons un chiffre - alors, puisque nous utilisons des parenthèses, nous retournons automatiquement cette correspondance avec cet idiome (pas la chaîne entière "recherchée"):

$ Perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = (\d)/ ; \
print "\n";'
3

... ainsi, pour capturer la chaîne recherchée dans son intégralité, nous devons l'encapsuler à nouveau entre parenthèses:

$ Perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = (\d))/ ; \
print "\n";'
Xy = 33

.... mais, nous n'obtenons pas ce que nous attendons, car maintenant il y a deux correspondances, $1 et $2; et apparemment l'idiome "print $str =~ /.../ "affiche toutes les correspondances (dans ce cas," $1$2 ").

Donc, pour obtenir uniquement la chaîne recherchée dans ce cas de correspondances imbriquées, nous avons maintenant pour spécifier explicitement uniquement $1:

$ Perl -e '$str="the variable Xy = 3 in this case"; $str =~ /(Xy = (\d))/ ; \
print "$1 \n";'
Xy = 3 

EDIT oct 2013: Via Attribuer l'une des multiples correspondances d'expression régulière à la variable en tant que ligne Perl (tableau de déréférence?) - cela peut également être fait pour une ligne unique:

$ Perl -e '$str="the variable Xy = 3 in this case"; \
print ( ( $str =~ /(Xy = (\d))/ )[1] ); print "\n";'
3

... cependant, notez la nécessité d'un second jeu de parenthèses enveloppantes pour que le print fonctionne directement avec le tableau regex retourné (anonyme?).

Enfin, dans un contexte multiligne, assurez-vous d'abord de "Slurp" le fichier/texte entier dans une seule chaîne; puis utilisez le /s (mode ligne unique = la nouvelle ligne est mise en correspondance) et /g (correspondances globales/multiples) - et enfin, assurez-vous que l'expression de correspondance est dans une boucle while, afin de parcourir toutes les correspondances:

$ echo "some data
IN
123
OUT
some more data
 is about to follow:
IN
256
OUT
done with data
out" | Perl -e '$str = do { local $/; <> }; while ($str =~ /(IN(.*?)OUT)/sg) { print "$1\n"} '

IN
123
OUT
IN
256
OUT

Eh bien, j'espère que cela aide quelqu'un,
À votre santé!

13
sdaau

Que diriez-vous simplement:

print $string =~ /Total Successful Transactions = (\d+)/;

Vous avez rarement besoin d'utiliser $1 et amis.

9
ysth
/(\d+$)/;
print $1;

Je suppose que vous voulez juste le numéro 195. Droite?

5
Parikshit

Vérifiez les derniers chiffres juste avant " et ..

#!/usr/bin/env Perl

use strict;
use warnings;

my $string = q{"2011-04-11 00:39:28,736::[main]::INFO (Main.Java:73) Test.Main::main() Total Successful Transactions = 195".};
my ($number) = $string =~ m{ (\d+) " \. \z}x;

print "Matched number: $number\n" if defined $number;
2
Alan Haggai Alavi

La version en ligne de commande de la réponse acceptée par @ markusk est assez compacte:

Perl -ne '/Total Successful Transactions = (\d+)/ && print "$1\n";'
2
Uri Cohen
my $str = '"2011-04-11 00:39:28,736::[main]::INFO (Main.Java:73) Test.Main::main() Total Successful Transactions = 195".';

$str =~ /Total Successful Transactions = (\d+)/;
print $1; 

195 seront stockés dans 1 $

2
Shalini

Ainsi:

if ("2011-04-11 00:39:28,736::[main]::INFO (Main.Java:73) Test.Main::main() Total Successful Transactions = 195" =~ /(\d+)$/) {
    print $1;
}

Une fois la correspondance établie, les groupes correspondants deviennent disponibles sous la forme $ 1 .. $ n.

0
Sajid