[PERL expreg] capture optionnelle ou EOL

Résolu
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 :

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

  1. Leviathan49 Messages postés 267 Statut Membre 70
     
    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é...
    1
  2. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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
    1
    1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      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
      
      0
    2. sbouli Messages postés 208 Statut Membre 2
       
      excellent, le print n'est là que pour faire jolie, je vais stocker en tableau uniquement les entrées de moins de 2 jours et donc purger les autres.
      Je vais donc parser la datehold et la matcher, DateTime est mon ami !

      Merci beaucoup à tout les 2 !!

      Stéphane
      0
  3. Leviathan49 Messages postés 267 Statut Membre 70
     
    Essaye Avec un regex de type ([^|]+)\|([^|]+)(?:\|([^|]+))?
    (?: ) = parenthèse non capturantes.
    0
  4. sbouli Messages postés 208 Statut Membre 2
     
    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
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    Si j'ai bien compris, quelque soit le nombre de champs tu veux récupérer juste les 2 premiers?
    0
    1. sbouli Messages postés 208 Statut Membre 2
       
      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
      0
    2. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      Re,

      Pour ce genre de situation split doit faire l'affaire vu qu'il y a un séparateur de champs.
      Perso c'est comme ça que j'aurais fait (même si j'aime bien les regex ;-)

      ($clef,$valeur,$datehold) = split "/\|/";
      0
    3. sbouli Messages postés 208 Statut Membre 2
       
      ç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
      ...
      
      0
  7. sbouli Messages postés 208 Statut Membre 2
     
    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
    0
    1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
       
      Re,

      Tu n'as pas répondu à ma question ;-)
      0