J'ai un script et un fichier.
[evelden@vatasu4435 perl]$ script file 35:42 35:42
Donc, à l'arrière de l'expression régulière, il est dit. *, mais pas au début.
Do,
[evelden@vatasu4435 perl]$ ./script file 06:35 foo 06:35
Apparemment. * à la fin prend autant que possible, ce qui est OK.
Mais ce que je Je ne comprends pas d'où vient «foo» dans la réponse. Telle est ma question.
Si je change l'expression régulière dans: s /.* (\ d \ d: \ d \ d). * / \ 1 /
, dus à l'avant également. *, alors la réponse est ce à quoi je m'attendais:
[evelden@vatasu4435 perl]$ cat file 06:35:42,734 foo 06:35:42 bar [evelden@vatasu4435 perl]$ cat script #!/usr/bin/perl while(<>){ if(s/(\d\d:\d\d).*/\1/){ print; } }
Maintenant, il est gourmand à l'avant, mais ça va.
3 Réponses :
Le contenu de la ligne courante est placé dans $ _
. Votre s ///
fonctionne sur ce $ _
, en remplaçant le modèle complet par le contenu de $ 1
(ou \ 1 code>, comme vous l'avez dit). C'est le contenu du premier groupe de capture du modèle. Mais votre modèle n'est pas ancré, il commencera donc à correspondre quelque part dans la chaîne et à remplacer à partir de là. Il fait exactement ce que vous lui avez dit.
Si vous vouliez vous débarrasser de tout ce qui se trouve à l'avant, votre deuxième motif est correct. Si vous souhaitez modifier uniquement les lignes qui commencent par le motif, utilisez une ancre ^
à l'avant.
Seule la partie de la ligne qui correspond à l'expression régulière est remplacée par s ///
. Puisque l'expression rationnelle n'est pas ancrée à gauche, elle correspond à la partie de la ligne commençant par l'heure et remplace cette partie. La partie avant la correspondance reste inchangée, donc foo
reste dans la ligne.
L'expression régulière originale d'OP ne précise pas où commencer ou terminer la capture.
s / (\ d \ d: \ d \ d). * / \ 1 /
- recherchez dans la chaîne\ d {2}: \ d {2}
et tout ce qui suit. Remplacez le modèle trouvé (\ d {2}: \ d {2}. *
- chiffres par tout ce qui le suit) par deux chiffres capturés\ d {2}: \ d {2}
. Il n'y a rien dans le modèle lié à ce qui est avant\ d {2}: \ d {2}
et aucun remplacement appliqué à cette partie -foo
n'est pas touché.
OP avait peut-être l'intention d'écrire le code suivant
06:35 06:35
Deux solutions simples au problème
use strict; use warnings; use feature 'say'; my $data = do { local $/; <DATA> }; my @time = $data =~ /\b(\d{2}:\d{2})/g; say for @time; __DATA__ 06:35:42,734 foo 06:35:42 bar
Ou une autre variante
use strict; use warnings; use feature 'say'; while(<DATA>) { /\b(\d{2}:\d{2})/; say $1; } __DATA__ 06:35:42,734 foo 06:35:42 bar
Ou peut être comme suit
use strict; use warnings; use feature 'say'; while(<DATA>) { /(\d{2}:\d{2}):/; say $1; } __DATA__ 06:35:42,734 foo 06:35:42 bar
Sortie
use strict; use warnings; s/.*?(\d{2}:\d{2}):.*/$1/ && print for <>;
Est-ce que
35:42
est vraiment ce que vous attendez, pas06:35
?Si vous voulez imprimer les heures, vous voulez
while (<>) {print "$ 1 \ n" while / (\ d \ d: \ d \ d) / g; }