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
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+)/;
}
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é!
Que diriez-vous simplement:
print $string =~ /Total Successful Transactions = (\d+)/;
Vous avez rarement besoin d'utiliser $1
et amis.
/(\d+$)/;
print $1;
Je suppose que vous voulez juste le numéro 195
. Droite?
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;
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";'
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 $
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.