IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Regex - Utilisation quantificateur non gourmand


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2015
    Messages
    138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2015
    Messages : 138
    Par défaut Regex - Utilisation quantificateur non gourmand
    Bonjour,

    j'ai en entrée la chaîne de caractères :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ressources=PRD_PenPenAXVI13 <> A TRAITER [liberation==oui]
    et souhaite extraire le nom de la ressource, ici PRD_PenPenAXVI13

    J'y arrive avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    if ( $str =~ /^ ([^\s]+) \s+ .+ $/x ) {
        push @{$r_h->{$env}->{'ressources'}->{$1}->{'jobs'}}, $job;
    }
    Par contre, je dois bugger sur un truc, je n'y arrive pas en utilisant les quantificateurs non gourmands !
    J'ai essayé /^ (.+) \s+? .+ $/x et diverses variantes pas meilleures comme /^ ((.+) \s)+? .+ $/x

    Si quelqu'un peut m'éclairer, parce que je tourne en rond sur ce point.

    Merci
    --
    Patrick

  2. #2
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 352
    Par défaut
    Pour que l'on puisse te donner une réponse correcte à ton besoin, il faudrait que tu nous dises ce que tu veux faire au juste, car tes regex ne semble pas du tout faire ce que tu veux, si dans ta chaine tu avais tototiti=tata djdjdj sjsjsj ça fonctionnerait aussi et $1 retournerait tototiti=tata...
    Et en dessous tu lui dis dit que c'est la valeur de ressources que tu veux et même pas sur la même variable...

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2015
    Messages
    138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2015
    Messages : 138
    Par défaut
    Désolé, je vais essayer de reformuler.

    L'entrée complète, listant les différentes ressources séparées par une virgule, est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ressources=PRD_PenPenAXVI13 <> A TRAITER [liberation==oui],PRD_PenPenAXVI31 = CFT CNTDF1 RECU [liberation==oui],PRD_PenPenAXVI32 = CFT CNTDF2 RECU [liberation==oui]
    Le code mis à jour pour cette partie est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    } elsif ( $record =~ /^ ressources= (.+) $/x ) {
         my @rsc = split /,/, $1;    # @rsc = ('PRD_PenPenAXVI13 <> A TRAITER [liberation==oui]' , 'PRD_PenPenAXVI31 = CFT CNTDF1 RECU [liberation==oui]' , 'PRD_PenPenAXVI32 = CFT CNTDF2 RECU [liberation==oui]')
     
         foreach my $str ( @rsc ) {
             if ( $str =~ /^ ([^\s]+) \s+ .+ $/x ) {
                 say $1;  # affiche  PRD_PenPenAXVI13 puis PRD_PenPenAXVI31 et enfin PRD_PenPenAXVI32
             }
        }
    }

    Mon besoin est donc d'extraire le nom de chaque ressource de ma chaîne de caractères et de l'afficher (say $1).

    J'y arrive avec l'expression régulière $str =~ /^ ([^\s]+) \s+ .+ $/x, mais cette solution ne me satisfait qu'à moitié, et je souhaiterai y arriver avec une expression régulière utilisant un quantificateur non gourmand

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 352
    Par défaut
    Ok, dans ce cas, interprétons tes regex:
    Sans le connecteur x, celle-ci est équivalente à:
    ^ ==> comme il est situer en début de regex, c'est pour dire "début de chaine"
    ([^\s]+) ==> au moins un caractère différent d'un type espace que l'on sauvegarde dans un argument (ici $1, puisque c'est le premier).
    \s+ ==> au moins un type d'espace
    .+$ ==> au moins quelque chose une fois.
    Tout ceci peut se traduire par prendre une chaine ne commençant pas par un type espace que l'on sauvegardera dans l'argument 1 si celle ci est suivant au moins d'un type espace + au moins un caractère quelconque avant de se terminer.

    Avec la suppression de gourmandise, il faut le penser légèrement différemment:
    prendre toute la chaine du début jusqu'au premier type espace non compris que l'on sauvegardera dans l'argument 1 si celle ci est suivant au moins d'un type espace + au moins un caractère quelconque avant de se terminer.
    ce qui donne:
    et si on rajoute le connecteur x, elle peut s'écrire:
    Ici, on utilise un '*' au lieu du '+' pour ne pas prendre en compte un espace en début de chaine (en gros, avec le '+' la suppression de la gourmandise commence à +1 alors qu'avec le '*' elle commence à +0.

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2015
    Messages
    138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2015
    Messages : 138
    Par défaut
    Merci, je teste cela demain et te tiens au courant.

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Bonsoir Patrick,

    je fais remarquer qu'avec ta première regex (quantificateurs avides ou gourmands), tu ne récupères pas le seul nom de la ressource (PRD_PenPenAXVI13) comme tu le dis dans le texte du post, mais la chaîne de caractères plus large du genre ressources=<nom_ressource>, comme on peut le voir dans ce test sous le debugger Perl.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      DB<1> $str = 'ressources=PRD_PenPenAXVI13 <> A TRAITER [liberation==oui]';
     
      DB<2> print $1 if $str =~ /^ ([^\s]+) \s+ .+ $/x
    ressources=PRD_PenPenAXVI13
    Le motif /^ ([^\s]+) \s+ .+ $/x capture tous les caractères autres que des espaces depuis le début de la chaîne jusqu'au(x) premier(s) caractère(s) de type espace (à condition cependant qu'il y ait encore au moins un caractère autre qu'un espace après le ou les espaces détectés par \s+ ).

    En fait, compte tenu de ce que tu cherches à faire et de la chaîne de caractères à analyser (et sachant qu'un motif n'a pas besoin de reconnaître toute la chaîne pour réussir, il suffit en sens inverse que le motif soit entièrement utilisé dans la reconnaissance), je pense que la seconde partie de la regex ne sert probablement à rien et que le motif /^([^\s]+)/ serait suffisant pour tes besoins:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      DB<3>  print $1 if $str =~ /^([^\s]+)/;     # Ou: /^ ([^\s]+)/x si tu préfères
    ressources=PRD_PenPenAXVI13
    Si tu veux absolument utiliser un quantificateur frugal ou non gourmand (je ne vois trop pourquoi, mais, bon, pourquoi pas?), alors on peut supposer que tu désires capturer tous les caractères depuis le début de la ligne jusqu'au premier espace, ce qui peut se traduire par le motif /^ (.+?) \s /x. Exemple sous le debugger:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      DB<4> print $1 if $str =~ /^ (.+?)  \s /x;
    ressources=PRD_PenPenAXVI13
      DB<5>

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/02/2015, 21h48
  2. Quelle expression Regex utiliser?
    Par l_informaticien dans le forum Général Java
    Réponses: 5
    Dernier message: 03/05/2013, 14h09
  3. Réponses: 2
    Dernier message: 18/09/2008, 10h49
  4. Regex: utilisation bbcode
    Par D_ident_1 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 25/07/2007, 00h00
  5. Utilisation de regex : TRegExpr
    Par trakiss dans le forum Langage
    Réponses: 2
    Dernier message: 22/06/2005, 23h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo