[PERL expreg] capture optionnelle ou EOL
Résolu
sbouli
Messages postés
208
Statut
Membre
-
sbouli Messages postés 208 Statut Membre -
sbouli Messages postés 208 Statut Membre -
Bonjour,
Je cherche à capturer un élément de manière optionnel :
aujourd'hui je fais :
qui me prend bien clef et valeur selon le |, mais je souhaiterais ajouter un élément optionnel correspondant à une date heure (ligne 2 de l'exemple) présente ou non après un |, j'ai bien bricoler un peu mais sans succès :
pourtant j'ai bien lu le bouquin sur les expressions régulières ... ça doit pas être sorcier ...
Merci d'avance pour votre aide !
Stéphane
Je cherche à capturer un élément de manière optionnel :
A1F712492D9B|info_46943_0_11111@domaine.com C55657BC738|info_48894_0_22222@domaine.com|20100826_121900
aujourd'hui je fais :
while (<FICHIER_HOLD>) {
(($clef,$valeur) = /([^|]+)\|(.*)$/i);
}
qui me prend bien clef et valeur selon le |, mais je souhaiterais ajouter un élément optionnel correspondant à une date heure (ligne 2 de l'exemple) présente ou non après un |, j'ai bien bricoler un peu mais sans succès :
([^|]+)\|([^|]+)\|([^|]+)
pourtant j'ai bien lu le bouquin sur les expressions régulières ... ça doit pas être sorcier ...
Merci d'avance pour votre aide !
Stéphane
6 réponses
-
Après quelques essai je te propose ceci : ([^|]+)\|([^|\s]+)(?:\|([^\s]+))?
Cela devrait marcher si tes champs entre pipe ne contiennent pas d'espaces, sinon ca va être plus compliqué... -
Re,
Oups, j'ai fait une erreur. Quand on mets les "" alors split considére qu'il s'agit d'une chaine de caractères. Donc c'est /\|/ et pas "/\|/"
Ensuite il faut juste faire un test pour print comme ça plus des warnings.
~ $ cat champs_underscore.pl #!/usr/bin/perl use strict;use warnings; while (<DATA>) { my ($clef,$valeur,$datehold) = split /\|/; if($datehold){ print "clef : $clef valeur : $valeur datehold : $datehold\n"; }else{ print "clef : $clef valeur : $valeur\n"; } } __END__ A1F712492D9B|info_46943_0_11111@domaine.com C55657BC738|info_48894_0_22222@domaine.com|20100826_121900 ~ $ perl champs_underscore.pl clef : A1F712492D9B valeur : info_46943_0_11111@domaine.com clef : C55657BC738 valeur : info_48894_0_22222@domaine.com datehold : 20100826_121900
GNU/Linux:Linux is Not Ubuntu! Quel linux choisir ne veut pas dire votre Distribution préférée,
106485010510997108-
Re,
Tu peux aussi utiliser l'opérateur ?: si tu veux, pour faire plus court ;-)
#!/usr/bin/perl use strict;use warnings; while (<DATA>) { my ($clef,$valeur,$datehold) = split /\|/; $datehold ? print "clef : $clef valeur : $valeur datehold : $datehold\n" : print "clef : $clef valeur : $valeur\n" ; } __END__ A1F712492D9B|info_46943_0_11111@domaine.com C55657BC738|info_48894_0_22222@domaine.com|20100826_121900 -
-
-
Essaye Avec un regex de type ([^|]+)\|([^|]+)(?:\|([^|]+))?
(?: ) = parenthèse non capturantes. -
je viens de tester avec The Regex Coach et ça ne semble pas faire ce que j'attends.
si je test sur une ligne avec uniquement 2 éléments, il poursuit sur la seconde ligne pour finir le second token.
si je test sur une ligne avec 3 éléments, il va finir le 3eme token sur la ligne suivante ....
au secours ...
Stéphane -
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
Salut,
Si j'ai bien compris, quelque soit le nombre de champs tu veux récupérer juste les 2 premiers?
-
bonjour lami,
non, je veux récupérer soit 2 champ soit 3 si le 3eme est présent.
2 formats possible pour chaque ligne :
champ1|champ2
ou
champ1|champ2|champ3
quand le champ3 n'existe pas, la variable vaut rien ou vide :
(($clef,$valeur,$datehold) = ([^|]+)\|([^|\s]+)(?:\|([^\s]+))?
ça me parait pas mal ....
Stéphane -
-
ça marche pas .... pourtant c'est plus logique et simple que l'expression régulière ....
while (<FICHIER_HOLD_FROM>) { ($clef,$valeur,$datehold) = split "/\|/"; print "clef : $clef valeur : $valeur datehold : $datehold\n"; }
donne :
Use of uninitialized value in concatenation (.) or string at /repertoire/fichier.pl line 112, <FICHIER_HOLD> line 1. Use of uninitialized value in concatenation (.) or string at /repertoire/fichier.pl line 112, <FICHIER_HOLD_FROM> line 1. clef : C55657BC738|infos_00000_0_111111@domaine.com valeur : datehold :
avec la source :
# cat fichier_hold.dat C55657BC738|infos_00000_0_111111@domaine.com ...
-
-
parfais, non il n'y aura pas d'espace, j'aurais jamais pensé à utilisé l'espace !
bravo
maintenant je test en live sur un fichier ... monstrueux :)
a+
Stéphane