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 :

regexp plusieurs séparateurs mais une seule valeur à extraire


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 9
    Points : 5
    Points
    5
    Par défaut regexp plusieurs séparateurs mais une seule valeur à extraire
    Bonjour,

    J'ai un petit soucis dans l'utilisation d'une expression régulière.

    En entrée, je possède une ligne d'un fichier de configuration (samba en l'occurence).
    L'idée est de séparer la zone de gauche de ma ligne, de celle de droite.
    La séparation est représentée par le signe "=".

    Exemple :
    workgroup = domaine1

    Jusque là, pas de problèmes. J'ai utilisé cette expression ci et tout semble fonctionner à merveille :
    $smb[$j] =~ /(.+)=(.+)/;
    my $section = $1;
    my $valeur = $2;


    section me donne > workgroup
    valeur me donne > domaine1

    En revanche, je ne m'en sors pas lorsque je dois traiter la ligne suivante :
    ldap admin dn = uid=sambamgr,o=test,c=fr

    Du fait de la présence de plusieurs signes "=", l'expression me renvoi des valeurs erronées :
    section me donne > ldap admin dn = uid=sambamgr,o=test,c
    valeur me donne > fr


    J'aimerais pouvoir créer une expression qui ne traite que le premier signe "=" rencontré.

    Ainsi je souhaiterais obtenir pour le second exemple :
    section > ldap admin dn
    valeur > uid=sambamgr,o=test,c=fr


    Si quelqu'un pouvait m'aider ou au moins me mettre sur la voie ce serait très sympa.

    Je vous remercie par avance.

  2. #2
    Membre habitué Avatar de lu6fer
    Inscrit en
    Avril 2008
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 141
    Points : 175
    Points
    175
    Par défaut
    Pour ton expression tu devrai matcher les espaces aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $chaine =~ /(.+)\s=\s(.+)/
    Comme ca il prendra le 1er '=' au lieu de prendre celui de la fin

    Puis ce que de toute facon la conf ldap ne doit pas contenir d'espaces, tu ne devrai t'en sortir qu'avec samba

  3. #3
    Futur Membre du Club
    Inscrit en
    Avril 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Merci pour cette réponse.

    En effet, ta solution fonctionne pour le cas où j'ai un espace avant et après le signe "=".
    Par contre, mes administrateurs ont la possibilité de modifier le smb.conf manuellement. Certains ne prennent pas soin de placer un espace avant et après et mon script ne fonctionnera pas pour les lignes telles que celles ci :


    workgroup=domaine1
    ldap admin dn=uid=sambamgr,o=test,c=fr
    logon path =


    Avec cette limitation supplémentaire, comment faire ?

    En tous les cas encore merci pour cette réponse.

    Par ailleurs, j'en profite pour demander si quelqu'un a connaissance d'un bon livre sur les expessions rationelles en perl ?

  4. #4
    Membre habitué Avatar de lu6fer
    Inscrit en
    Avril 2008
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 141
    Points : 175
    Points
    175
    Par défaut
    peut etre comme ceci alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $chaine =~ /(.+)\s?=\s?(.+)/

  5. #5
    Futur Membre du Club
    Inscrit en
    Avril 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Malheureusement ça ne fonctionne pas avec cette fameuse chaine :

    ldap admin dn = uid=sambamgr,o=test,c=fr

    Résultat :
    ldap admin dn = uid=sambamgr,o=test,c
    et : fr


    Je ne parviens pas à comprendre pourquoi ce n'est pas le premier caractère "=" qui est traité mais le dernier.
    Quelqu'un aurait une explication à ce sujet ?

    Merci d'avance.

  6. #6
    Futur Membre du Club
    Inscrit en
    Avril 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Je viens de comprendre pourquoi cette expression me prenait le dernier signe "=" au lieu du premier.
    Voici l'expression :
    $chaine =~ /(.+)=(.+)/

    Et la chaine sur laquelle elle s'applique :
    my $chaine = ldap admin dn = uid=sambamgr,o=test,c=fr

    En fait si j'ai bien compris le perlretut, il s'agit d'un problème de gourmandise.

    En effet, je demande à mon expression de me trouver n'importe quel caractère (.+) suivi d'un signe "=" puis n'importe quel caractère (.+).
    Le premier caractère "=" rencontré est bien celui situé le plus à gauche. En revanche, la première partie de l'expression (.+) va tenter de prendre le plus long résultat possible. En parcourant la chaine jusqu'au bout, elle va trouver un dernier signe "=" rendant possible un résultat différent de celui attendu.
    En résumé, la gourmandise de cette expression me renverra "ldap admin dn = uid=sambamgr,o=test,c" puis "fr".

    Je ne sais pas si j'ai été clair mais j'espère que cela pourra profiter à quelqu'un dautre.
    Maintenant il me reste à trouver une solution pour que mon expression fonctionne.

  7. #7
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    La gourmandise est effectivement le problème, tu pourrais donc simplement utiliser les quantificateurs paresseux pour régler ton problème mais il y a une meilleure solution :
    --
    Jedaï

  8. #8
    Membre habitué Avatar de lu6fer
    Inscrit en
    Avril 2008
    Messages
    141
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 141
    Points : 175
    Points
    175
    Par défaut
    au lieu de mettre (.+), essaye avec (.+?)

    le +? est la version non gourmande de +, cela devrait fonctionner

    j'ai tester avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/perl
    #
    use warnings;
    use strict;
     
    while (<>) {
            $_ =~ /^(.+?)\s?=\s?(.+)$/;
            print "section => ".$1."\n";
            print "valeur => ".$2."\n";
    }
    avec comme fichier d'entree :
    workgroup = domaine1
    ldap admin dn = uid=sambamgr,o=test,c=fr
    workgroup=domaine1
    ldap admin dn=uid=sambamgr,o=test,c=fr
    et le resultat est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    section => workgroup
    valeur => domaine1
    section => ldap admin dn
    valeur => uid=sambamgr,o=test,c=fr
    section => workgroup
    valeur => domaine1
    section => ldap admin dn
    valeur => uid=sambamgr,o=test,c=fr

  9. #9
    Futur Membre du Club
    Inscrit en
    Avril 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Merci infiniment pour cette solution.
    En effet, elle fonctionne parfaitement.
    Dans l'entre-temps, j'avais pu tester cette solution ci que j'allais justement poster ici :

    /(.*?)=(.*)/;


    Je pense que c'est ce que tu appeles les quantificateurs paresseux ?
    Si j'ai bien compris, le "?" permet à l'expression (.*) de ne s'appliquer qu'une seule fois avant le signe "=".

    Dans le cas de cette expression ci :
    m/([^=]+)=(.+)/
    Tu cherches à matcher tout ce qui précède le signe "=" mais qui n'est pas "=" ? (pour la première partie).

    En tous les cas encore une fois un grand merci pour ces renseignements.

    Bonne journée à tous.

  10. #10
    Futur Membre du Club
    Inscrit en
    Avril 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Excuse moi lu6fer, je n'avais pas vu ton post.

    Tu réponds donc à ma question précédente concernant la gourmandise.

    Merci beaucoup.

  11. #11
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par RaF25 Voir le message
    Dans le cas de cette expression ci :
    m/([^=]+)=(.+)/
    Tu cherches à matcher tout ce qui précède le signe "=" mais qui n'est pas "=" ? (pour la première partie).
    C'est exactement ça. Ta première partie ne comporte aucun "=", donc cette expression est plus descriptive à mon sens, de plus elle utilise des fonctionnalités plus connues que les quantificateurs paresseux pour la plupart des utilisateurs de regexps et elle est également plus efficace. Il vaut mieux éviter en général les quantificateurs paresseux quand il y a une solution simple alternative comme ici.

    --
    Jedaï

  12. #12
    Futur Membre du Club
    Inscrit en
    Avril 2008
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Ce n'est pas toujours simple à comprendre mais ça commence à venir.

    J'ai bien noté tes conseils et je m'attacherai à les appliquer autant que possible.

    Encore une fois merci. Je n'aurais pas avancé aussi rapidement sans votre aide à tous les deux.

    Bonne journée.

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

Discussions similaires

  1. [AC-2010] Liste déroulante avec plusieurs colonnes mais une seule affichée
    Par scorpking dans le forum IHM
    Réponses: 2
    Dernier message: 23/01/2014, 13h07
  2. Plusieurs inconnus mais une seul équation
    Par soft001 dans le forum Mathématiques
    Réponses: 13
    Dernier message: 09/04/2012, 14h47
  3. CR XI : Renseigner plusieurs paramètres avec une seule valeur
    Par jpamy dans le forum SAP Crystal Reports
    Réponses: 0
    Dernier message: 30/01/2009, 14h22
  4. [WPF-Blend] Plusieurs objets mais une seule animation
    Par Tuizi dans le forum Framework .NET
    Réponses: 12
    Dernier message: 11/12/2007, 17h10
  5. Récupérer une seule valeur parmi plusieurs
    Par geraldgg dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 11/05/2007, 10h26

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