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

C# Discussion :

[Expression Reguliere] Aide pour la création d'une expression


Sujet :

C#

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 45
    Points : 22
    Points
    22
    Par défaut [Expression Reguliere] Aide pour la création d'une expression
    Bonjour à tous!

    Je suis un débutant et je ne maitrise pas beaucoup les expressions régulières mais j'ai l'impression que je dois les utiliser pour ma problématique.

    J'ai une chaine qui ressemble à ca: "toto = 1 and titi != 3 or tata = 4"
    donc on ne connait pas le nombre de "or" et de "and".

    Et ce que j'aimerais c'est avoir un tableau qui contient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    -----------------
    |toto = 1  | and |
    -----------------
    |titi != 3  | or |
    -----------------
    |tata = 4   |    |
    -----------------
    Mais je ne comprends pas comment gérer la répétition à l'infini :S
    J'y arrive bien lorsqu'il y a deux condition en faisant:
    mais après ca se complique...

    Ça doit vous paraitre bateau comme problème mais je suis loin d'être un développeur et vous avez toujours été très pédagogue avec moi donc je reviens encore vous voir...

    Je n'ai pas trouvé de sous-forum dédié aux expressions régulière alors je me suis permis de poster ici vu qu'à terme c'est pour l'intégrer dans du c#.

    Merci beaucoup!
    Cordialement

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2007
    Messages : 125
    Points : 109
    Points
    109
    Par défaut
    Bon, je suis pas du genre à te mâcher le boulot,
    mais t'es pas si mal parti...ton expression est juste mal découpée:
    demande-toi comment tu rajoutes des "assignations" ("titi = 1") et comment tu agences tes mots-clef entre eux; ça devrait te faire modifier ta Regexp (Expression regulière).


    Hope this helps...
    ElTchoupi

  3. #3
    Max
    Max est déconnecté
    Expert éminent sénior

    Avatar de Max
    Homme Profil pro
    Artisan développeur
    Inscrit en
    Mai 2007
    Messages
    2 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Artisan développeur
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2007
    Messages : 2 954
    Points : 14 933
    Points
    14 933
    Par défaut
    Salut.

    Je ne devrais pas, mais je vais te donner un truc qui correspond à peu près ce que tu recherches :
    ^(?<name>\w+)(\s(?<operator>=|!=)\s)(?<value>\d+)(\s(?<logicalOperator>and|or)\s(?<name>\w+)(\s(?<operator>=|!=)\s)(?<value>\d+))*$
    Pour pouvoir ensuite l'utiliser et construire ton tableau, bah, tu vas être obligé de comprendre comment elle fonctionne . Pour cela, tu peux utiliser le logiciel Expresso qui décomposera bien tous les morceaux.

    Je conclurai en disant que les regex, c'est comme le plastique, c'est fantastique .

    P.S. : au passage, je ne peux que te conseiller de lire les excellents tutoriels de Louis-Guillaume Morand et de StormimOn sur le sujet, qui, selon moi, sont des références en la matière.

  4. #4
    Membre habitué Avatar de swif79
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2009
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2009
    Messages : 79
    Points : 169
    Points
    169
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    List<string> matchList = new List<string>();
                string toto = "toto = 1 and titi != 3 or tata = 4 or toto = 1 and titi != 3 or tata = 4 and toto = 1 and titi != 3 or tata = 4 or toto = 1 and titi != 3 or tata = 4 and toto = 1 and titi != 3 or tata = 4";
                Regex reg = new Regex(@"([a-zA-Z]+)\s(=|!=)\s([0-9]+)\s?(and|or)?");
                if (reg.IsMatch(toto))
                {
                    MatchCollection coll = reg.Matches(toto);
     
                    foreach (Match m in coll)
                    {
                        matchList.Add(string.Format("|{0} {1} {2} | {3} |",
                                        m.Groups[1].Value,
                                        m.Groups[2].Value,
                                        m.Groups[3].Value,
                                        m.Groups[4].Value));
                    }
                }

  5. #5
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 45
    Points : 22
    Points
    22
    Par défaut
    Bonjour à tous,

    Alors, pour ElTchoupi, moi non plus je n'aime pas qu'on m'apporte la solution sur un plateau, du coup j'ai adoré ton post pour me mettre sur les rails.

    Pour _Max_, grâce à toi j'ai découvert qu'on pouvait mettre des noms à des résultats Et oui, au premier abord je me suis dit que tu lisais une ligne xml mais non non non!
    D'après ce que j'ai compris, tu prends un premier enregistrement où tu places les valeurs dans name, operator et value. Puis tu cherches 0 ou n fois un and ou or que tu places dans logicalOperator suivi de de valeurs que tu mets dans name, operator et value.
    Me trompe-je?
    J'ai essayé d'adopter la même idée pour mon cas mais je dois mal l'écrire parce que ca part n'importe comment...

    Pour les tutoriels, celui de Louis-Guillaume Morand, je l'avais déjà lu et c'était exactement l'état de mes connaissances lorsque j'ai fait mon topic. Et celui de StormimOn je l'ai découvert et j'ai adoré (surtout les schéma). Bon je ne maitrise pas encore tout par manque de pratique mais j'ai compris pas mal de choses, ma plus grande découverte à été que les expressions régulières sont "greedy" ce qui posait problème dans mon cas.

    Pour swif79, merci de ta solution toute cuite mais j'ai envie de chercher ma solution, même si elle est moins bonne que la tienne, j'aurais la satisfaction de l'avoir faite avec mes petites mains.
    Cela dit, grâce à toi j'ai découvert qu'il pouvait y avoir plusieurs "matches" qui contiennent plusieurs valeurs. Alors que moi je croyais qu'il n'y avait toujours qu'un match avec toutes les valeurs à la suite.

    Si je peux rajouter un détail, l'opérateur peut-être autre chose que = ou !=, cela peut-être un mot. La valeur n'est pas forcément un chiffre.
    C'est pourquoi j'ai dans l'idée de récupérer tous les caractères entre un and ou or, c'est plus simple.

    Voici donc l'état actuel de ma regexp:
    Mon seul problème c'est que je n'arrive pas à envoyer un dernier match pour ce qu'il y a après le dernier 'and' ou 'or'.
    Voilà ce que j'ai aussi essayé et qui ne me convient pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ((.*)\s(or|and)\s)*(.*)
    (.*)((and|or)(.*))*
    (.*?)\s(or|and)\s(.*)$
    Est ce que je suis toujours sur la bonne voie? parce que j'ai l'impression de m'éparpiller... Et si oui, est-il possible d'avoir un indice (sans code) pour savoir comment récupérer ma dernière partie de chaine.

    Merci beaucoup de toute votre aide! Infiniment, beaucoup!

    Bonne journée

  6. #6
    Max
    Max est déconnecté
    Expert éminent sénior

    Avatar de Max
    Homme Profil pro
    Artisan développeur
    Inscrit en
    Mai 2007
    Messages
    2 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Artisan développeur
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2007
    Messages : 2 954
    Points : 14 933
    Points
    14 933
    Par défaut
    Salut.

    Alors pour ma part, l'exemple que je t'ai fourni est prévu pour fonctionner de façon "stricte" avec l'exemple de chaîne que tu as donné :
    "toto = 1 and titi != 3 or tata = 4" dont on ne connait pas le nombre de "or" et de "and"
    Citation Envoyé par jeremdu94 Voir le message
    D'après ce que j'ai compris, tu prends un premier enregistrement où tu places les valeurs dans name, operator et value. Puis tu cherches 0 ou n fois un and ou or que tu places dans logicalOperator suivi de de valeurs que tu mets dans name, operator et value.
    Me trompe-je?
    C'est exactement ça : mon expression impose la présence d'au moins une séquence du type :
    toto = 1
    correspond à
    ^(?<name>\w+)(\s(?<operator>=|!=)\s)(?<value>\d+)
    Puis elle récupère une par une les autres :
    and titi != 3 PUIS or tata = 4 etc.
    correspond à
    (\s(?<logicalOperator>and|or)\s(?<name>\w+)(\s(?<operator>=|!=)\s)(?<value>\d+))*$
    Citation Envoyé par jeremdu94 Voir le message
    Bon je ne maitrise pas encore tout par manque de pratique mais j'ai compris pas mal de choses, ma plus grande découverte à été que les expressions régulières sont "greedy" ce qui posait problème dans mon cas.
    Si tu utilises plein de fois la même regex, tu peux la compiler, ça améliore les performances :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Regex myRegex = new Regex("^(.*)$",   RegexOptions.Compiled);
    Citation Envoyé par jeremdu94 Voir le message
    Pour swif79, grâce à toi j'ai découvert qu'il pouvait y avoir plusieurs "matches" qui contiennent plusieurs valeurs. Alors que moi je croyais qu'il n'y avait toujours qu'un match avec toutes les valeurs à la suite.
    <modeCommercial>Un outil comme celui que je t'ai conseillé te montre tout de suite ce genre de chose </modeCommercial>
    Citation Envoyé par jeremdu94 Voir le message
    Si je peux rajouter un détail, l'opérateur peut-être autre chose que = ou !=, cela peut-être un mot. La valeur n'est pas forcément un chiffre. C'est pourquoi j'ai dans l'idée de récupérer tous les caractères entre un and ou or, c'est plus simple.
    Avec cette méthode, tu ne fais que reculer l'échéance, car après avoir récupéré tous ces caractères, il va falloir les retraiter pour distinguer les variables des opérateurs. Personnellement, en prenant l'exemple de l'opérateur, je ferais joujou avec les alias pour extraire directement l'opérateur ([\w=!<>]+ peut être un début...)
    Citation Envoyé par jeremdu94 Voir le message
    Voici donc l'état actuel de ma regexp:
    Mon seul problème c'est que je n'arrive pas à envoyer un dernier match pour ce qu'il y a après le dernier 'and' ou 'or'.
    Voilà ce que j'ai aussi essayé et qui ne me convient pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ((.*)\s(or|and)\s)*(.*)
    (.*)((and|or)(.*))*
    (.*?)\s(or|and)\s(.*)$
    Est ce que je suis toujours sur la bonne voie? parce que j'ai l'impression de m'éparpiller... Et si oui, est-il possible d'avoir un indice (sans code) pour savoir comment récupérer ma dernière partie de chaine.
    Personnellement, je pense qu'effectivement tu t'éparpilles, tes regex sont beaucoup trop floues et génériques, et du coup tu perds tout l'intérêt des regex en procédant comme cela, mais ce n'est que mon avis .

    Toute la difficulté réside dans le fait de créer un truc suffisamment générique pour traiter le maximum de cas, mais pas trop pour ne pas matcher avec n'importe quoi. Un exemple, la chaîne "les regex c'est top or c'est pas top ça depend des gens", bah elle matche avec toutes les expressions que tu as proposées plus haut , et on est quand même a mille lieues de ce que tu cherches à parser .

  7. #7
    Membre habitué Avatar de swif79
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2009
    Messages
    79
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2009
    Messages : 79
    Points : 169
    Points
    169
    Par défaut
    Bonjour jeremdu94,

    Si j'ai utilisé une MatchCollection c'est parce que dans ton premier post tu dis

    Citation Envoyé par jeremdu94 Voir le message
    J'ai une chaine qui ressemble à ca: "toto = 1 and titi != 3 or tata = 4"
    donc on ne connait pas le nombre de "or" et de "and".
    Citation Envoyé par _Max_
    Personnellement, je pense qu'effectivement tu t'éparpilles, tes regex sont beaucoup trop floues et génériques, et du coup tu perds tout l'intérêt des regex en procédant comme cela, mais ce n'est que mon avis .

    Toute la difficulté réside dans le fait de créer un truc suffisamment générique pour traiter le maximum de cas, mais pas trop pour ne pas matcher avec n'importe quoi. Un exemple, la chaîne "les regex c'est top or c'est pas top ça depend des gens", bah elle matche avec toutes les expressions que tu as proposées plus haut , et on est quand même a mille lieues de ce que tu cherches à parser .
    Totalement d'accord

    Citation Envoyé par jeremdu94 Voir le message
    Si je peux rajouter un détail, l'opérateur peut-être autre chose que = ou !=, cela peut-être un mot. La valeur n'est pas forcément un chiffre.
    C'est pourquoi j'ai dans l'idée de récupérer tous les caractères entre un and ou or, c'est plus simple.

    Voici donc l'état actuel de ma regexp:
    Je crois que tu n'a pas encore bien compris , là si ont prend l'exemple de max ou le mien il y as vraiment peu à faire pour ce résultat.
    Quand je regarde tes derniers exemples, je ne comprends pas pourquoi tu utilise * et encore moins * suivie de ?...
    Je te conseille fortement de lire à nouveau quelques cours sur les expressions régulières, courage

Discussions similaires

  1. Aide pour la création d'une requête
    Par Marc_27 dans le forum IHM
    Réponses: 1
    Dernier message: 15/12/2008, 12h26
  2. Aide pour la création d'une vue
    Par bossun dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/07/2008, 09h19
  3. besoin d'aide pour la création d'une requête
    Par fabien59420 dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 11/06/2008, 15h29
  4. Réponses: 3
    Dernier message: 26/06/2007, 14h53
  5. Réponses: 2
    Dernier message: 10/03/2006, 13h55

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