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 régulière, résolution d'un soucis gênant.


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut Expression régulière, résolution d'un soucis gênant.
    Bonjour,

    Cela ne fait pas longtemps que je me sert de ce forum, en fait depuis que j'apprends le C.

    Je reviens vers vous car entre temps j'ai rencontrer des petits soucis d'expression régulière.

    Je m'explique, à mon programme je passe des arguments, que je récupère.

    J'ai une fonction " regtest ", à laquelle je donne mon expression régulière et la chaine à tester.

    Dans le cas ou j'ai la chaine " 123 " à tester (sans les espaces), ça fonctionne quand j'utilise comme expression [0-9].

    Par contre, je ne comprends pas, quand j'utilise [:digit:] ça ne fonctionne pas, pourquoi ?

    En outre, quand j'ai comme chaine à tester " test² " (avec le 2 exposant), et que j'ai comme expression régulière : " [-_[:alnum:]] ", il laisse passer la chose.

    la chaine récupéré passe par un algo de chiffrage qui n'est pas de mon cru, et une fois déchiffrer cet algo me met " zz " à la place du " ² ".

    Je ne comprends vraiment pas ou est l'erreur, si quelqu'un pourrait éclairer ma lanterne sur le sujet ça m'arrangerais car je perds la tête.

    Pour info pour m'aider j'ai utiliser ce liens dispo sur le site :

    http://nicolasj.developpez.com/articles/regex/

    Voila, en espérant que comme à l'habitude quelqu'un puisse m'aider ...

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    L'opérateur de regex [ ] est un opérateur signifiant "l'un de ceux-ci".
    il accepte un ensemble de valeurs, qui sont spécifiables de plusieurs moyens.
    • explicitement: [akl] accepte un a, un k ou un l
    • par série: [c-g] accepte tout caractère compris entre c et g (inclus) (attention aux locales…
    • par classes [:digit:] est une classe. du coup, [[:digit:]] est un selecteur (chiffres base 10), de meme que [[:digit:]A-F] (chiffres bases 16 majuscules)


    Ton erreur est de confondre les corchets de la classe avec ceux de l'opérateur

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut Merci
    Ah d'accord, je ne confondais pas, je ne savais pas que [:digit:] était une classe, donc dans la logique ça ne peut pas marché.

    En gros, [[:digit:]] c'est la classe équivalente à [0-9], la c'est plus claire.

    Sinon du reste, " ² " qui devient " zz ", une idée ?

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Ça, je n'en sais rien.

    Fais particulièrement attention à la différence entre séquences et classes. [:alpha:] n'est pas strictement a-zA-Z, surtout s'il y a des caractères accentués dans la locale actuellement utilisée.
    Il faut garder cette différence dans un coin de la tête quand tu utilises les regex.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut
    l'expression régulière qui teste cette argument entrée est :
    [-_[:alnum:]]

    donc, alum n'est pas strictement non plus a-z et A-Z.

    En outre, est-ce correcte d'écrire [a-zA-Z] ? ou dois-je écrire plutot :

    [[a-z][A-Z]] ?

    Je pense que tu aura compris que c'est la première fois que j'ai affaire aux expressions régulière, je viens du monde VB ou de telles choses peuvent être faite dans les controles de façon dynamique très facilement ... comme c'est un programme console que je développe l'optique n'est pas la même.

  6. #6
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    [a-zA-Z] est une regex, [[a-z][A-Z]] n'en est pas une. (dans aucune syntaxe acceptée par C++11, en tout cas)

    [:alnum:] est logiquement "tout caractère alphabétique ou numéral"
    tu y trouve au minimum les minuscules et majuscules de base, mais tu peux aussi y trouver les accents âàäêéèëöôùüïî, ÂÄÀÊÉÈËÖÔÙÜÏÎ, et aussi le ç

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut Précision
    Merci pour ces infos,

    je n'arrive tjr pas à éliminé le ² passer en argument, je vais voir si avec un fgets il récupère le ² ou pas, ou s'il le converti en " zz " comme c'est le cas quand c'est un argument passer au programme.

    Comme je ne fais qu'un API dans le programme général, ce ne sera donc pas des arguments qui seront passer mais des variables, donc ça ne posera pas de problème.

    Merci pour ces infos, je ne met pas encore résolu car je n'ai pas encore tout corriger, je pense que des questions viendrons dans la journée.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut
    voila un exemple de questions pertinante.

    j'ai fais une expression régulière pour tester un mail :

    [.-_[:lower:][:digit:]]+@+[.-_[:lower:][:digit:]]+.+[[:lower:]{2,4}]

    Je pense qu'elle doit être juste, du moins jusqu'à l'arobase.

    Après, je rencontre des soucis, par exemple si je teste :

    test@test, ça fonctionne, mais il manque le .fr ... et ça passe tout de même, je ne comprends pas.

  9. #9
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par enzo68290 Voir le message
    Merci pour ces infos,

    je n'arrive tjr pas à éliminé le ² passer en argument, je vais voir si avec un fgets il récupère le ² ou pas, ou s'il le converti en " zz " comme c'est le cas quand c'est un argument passer au programme.

    Comme je ne fais qu'un API dans le programme général, ce ne sera donc pas des arguments qui seront passer mais des variables, donc ça ne posera pas de problème.

    Merci pour ces infos, je ne met pas encore résolu car je n'ai pas encore tout corriger, je pense que des questions viendrons dans la journée.
    Bonjour,
    Attention le caractère ² n'est pas contenu dans le code ascii et tout va dépendre de l'encodage que tu utilises (UTF8, ISO8859, ...). Évidemment la bibliothèque gnu que tu utilises se restreint au code ascii (0-127) ...

  10. #10
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    '.' est l'opérateur signifiant "un caractère quelconque", sauf dans un []. Il faut utiliser \. pour dire désigner un '.' explicitement.

    Par ailleurs, dans l'absolu, une adresse mail est terrible par exemple "moi+toi@nowhere.in.the.net" est envisageable et je reste gentil. J'aurais pu parler de moi+toi.nous+serons+heureux@10.0.0.1

    Pour respecter scrupuleusement la norme, la regex est affreuse.
    Par exemple, vois la regex pour perl.

    Et ca, c'est je ne suis même pas sûr que ce soit vraiment complet

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut
    Citation Envoyé par kwariz Voir le message
    Bonjour,
    Attention le caractère ² n'est pas contenu dans le code ascii et tout va dépendre de l'encodage que tu utilises (UTF8, ISO8859, ...). Évidemment la bibliothèque gnu que tu utilises se restreint au code ascii (0-127) ...
    quand tu parle d'encodage, uft8 par ex, cela concerne quoi ? et quand tu parle de la bibliothèque gnu, pareil, ou je paramètre cette variable ?

    Est ce que pour faire ces modifications touchent le makefile, ou l'encodage de mes fichier.c ou .h / makefile ?

    A savoir que le makefile m'a été fournit pour mon testeur de donnée, ou les fichiers que je codes sont inclu comme bibliothèque dans le projet déjà existant.

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut
    Oula, si j'ai bien compris c'est une regex de mail ???? c'est tout simplement abusif ...

    Si j'en veux une simple qui générise et autorise ça sans trop tester, ce basé sur ce que j'ai écris est-il possible ?

    J'en est fait une des plus simples, qui cette fois fonctionne après quelques corrections.

    Je savais qu'il fallait échapper le point, mais quand je le protégeais ça buggais. Je n'avais pas imaginé qu'il fallait échapper le caractère d'échappement qui allait lui-même échapper le point, du coup ça fonctionne :

    [\\.-_[:alnum:]]+\\@+[\\.-_[:alnum:]]+\\.+[a-z]{2,4}

    ça servira peut être à quelqu'un.

  13. #13
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    le @, tu t'en moques de l'échapper.
    par contre avec les nouveaux TLD (top level domain) autorisés par l'ICANN, le bloc terminal n'est pas valable. En effet, .carrefour peut exister, et des noms non latins (grec, chinois, arabe…)
    par ailleurs, tu ne peux pas avoir deux . consécutifs.

    Pour te simplifier la vie, tu peux aussi diviser le test.
    genre regex("[\\.-_[:alnum:]]+\\@+[\\.-_[:alnum:]]+") && not find("..")

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut
    Il est vrai par exemple que .carrefour peut exister ... je vais tester et je te ferais un retour.

    Ah et merci pour l'arobase, du coup j'ai tout échappé ^^.

    En outre maintenant, j'ai besoin de tester une chaine qui peut contenir de l'alphanumérique majuscule minuscule, et tiret / underscore.

    Je n'arrive pas à généré la regex qui va dans se sens, impossible de faire fonctionner la chose, une idée ?

    je partais sur :

    [[a-zA-Z][:digit:]-_]

    celle-ci ne laisse rien passer, " test12-_ " ne match pas, donc elle n'a pas l'effet escompté, j'ai aussi essayé ça mais sans succès, mais la tout passe :

    [-_[:alnum:]]

  15. #15
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Dans un [], le '-' n'est lui même que s'il est le premier caractère (ou peut être le dernier).
    de meme, le '^' en première position signifie "tout ce qui n'est pas dans ce choix", ainsi "[^;.]" signifie "un caractère qui n'est ni un ';' ni un '.'

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut
    Je vois que j'ai encore beaucoup à apprendre.

    donc le début est obligatoirement : [-_ suivit d'autre chose, jusque la ok.

    Comment ce fait-il que quand je teste : " test-_12 "

    avec l'expression régulière suivante (qui respecte donc le fait que le tiret soit en premier) :

    [-_[a-zA-Z][:digit:]]

    ma fonction de teste me renvoie que ça ne match pas ?

    j'ai essayé avec :

    [-_[a-Z]] avec comme valeur à tester : " test-_ ", et j'obtiens tjr pareil, soit je ne comprends pas soit il me manque encore des infos.

  17. #17
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    [] reconnaît un unique caractere
    [-_[a-zA-Z][:digit:]] est mal formé, c'est deux selecteurs [-_[a-zA-Z], puis [:digit:] et un symbole ]
    cela pourrait reconnaitre "_:]" (à supposer que : puisse etre écrit deux fois dans un selecteur)
    Tu as une paire de [] en trop (autour de a-zA-Z) et il te manque un opérateur de multiplicité, que ce soit *, +, {8}, {2,10} ou {8,}

    Pour t'aider un peu, une regex peut être construite par récursion comme:
    • un unique symbole, qui reconnait ce symbole
    • un '.' qui reconnait n'importe quel symbole
    • un sélecteur [], qui reconnait un symbole parmi ceux mentionné
    • un antisélecteur [^] qui reconnait tout symbole non mentionné
    • (regex) qui reconnait ce que reconnait regex
    • union ou choix: r1|r2 qui reconnait tout ce que reconnait r1 et tout ce que reconnait r2
    • enchainement: ER, la concaténation de deux regex (ici E et R)). Reconnait exactement toute chaine pouvant être divisée en deux morceaux, le premier étant reconnu par E, le second par R.
    • lazy (paresseux): (regex)? ce que reconnait regex ou rien du tout
    • multiplicité fixe: (regex){n} reconnait tout ce qui peut être découpé en exactement n morceaux, chacun reconnu exactement par regex
    • multiplicité limité: (regex){m,n} reconnait tout ce qui peut être découpé en un nombre de morceaux compris inclusivement entre m et n, chacun reconnu exactement par regex
    • multiplicité max: (regex){,n} reconnait tout ce qui peut être découpé en au plus n morceaux, chacun reconnu exactement par regex
    • multiplicité min: (regex){m,} reconnait tout ce qui peut être découpé en au moins n morceaux, chacun reconnu exactement par regex
    • multiplicité ouverte: (regex)+ qui est exactement (regex){1,}
    • étoile de Kleen: (regex)* qui est exactement (regex){0,} ou encore (regex)+?


    ce que peut contenir un sélecteur []:
    • un symbole non mot clé, ou précédé d'un \, qui est reconnu comme tel (hormis le '-' et le ']')
    • un '-' au début ou à la fin, qui est reconnu comme tel
    • un '^' pas au début, qui est reconnu comme tel. (le '^' au début inverse l'opérateur)
    • un ']' au début, qui est reconnu comme tel (sinon, c'est la fin de l'opérateur)
    • une portée a-c, qui reconnait tout symbole situé entre a et c (tous deux inclus)
    • une classe prédéfinie, telle que [:alnum:] (ces crochets font partie du nom de la classe)

    Pour reconnaitre le '-' et le ']', il faut faire quelque chose comme "[]abc-]" (qui reconnait l'un des cinq caracteres 'a', 'b', 'c', '-' et ']')

    Précision: l'échappement ne fonctionne pas dans les sélecteurs.

    Je pense avoir été assez complet pour tes besoins.

    Il existe encore les références (la regex "([a-z]*)\1" est censé reconnaitre un séquence de caractères quelconque, suivi d'exactement la même, donc "aa", "abcabc" et ""), mais la syntaxe devient vachement sioux.

    L'ensemble des regex sans références est modélisable par des machines à états finis, cela pourrait t'aider à comprendre.

    PS: en viô françois, "match" se traduit par reconnaitre.

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 86
    Par défaut
    Et bien franchement, je te remercie d'avoir passer autant de temps à me répondre, si avec toutes ces informations je ne finis pas par arriver à mes fins, c'est que je dois retourner à l'école.

    En outre, merci pour " reconnaitre ", je cherchais le mot qui convient mais n'en est pas trouvé, alors qu'il est tout bête ... ^^.

    Avec mes excuses pour t'avoir fait perdre ton temps, et mes remerciements pour l'aide donnée, je vais passer ce post en résolu avec encore un grand merci.

  19. #19
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Il n'y a pas de quoi, nous sommes là pour ça.

    Si ca t'es utile, n'hésite pas à voter pour mes interventions, en cliquant sur les
    C'est vrai dans tous les sujets, mais pour cette fois, c'est moi pour

    Au passage, c'est inutile de citer intégralement le dernier message, vu qu'il est juste au dessus.

    Bon courage, et bonne continuation!

  20. #20
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par enzo68290 Voir le message
    quand tu parle d'encodage, uft8 par ex, cela concerne quoi ? et quand tu parle de la bibliothèque gnu, pareil, ou je paramètre cette variable ?

    Est ce que pour faire ces modifications touchent le makefile, ou l'encodage de mes fichier.c ou .h / makefile ?

    A savoir que le makefile m'a été fournit pour mon testeur de donnée, ou les fichiers que je codes sont inclu comme bibliothèque dans le projet déjà existant.
    Tu vas te tirer les cheveux du crâne ... ça ne se paramètre pas en soi à un seul endroit. L'idéal étant de choisir un encodage de travail interne à l'application, puis pouvoir déterminer l'encodage utilisé par l'environnement d'exécution et transcoder de l'un à l'autre quand nécessaire. L'encodage utilisé pour les sources reste secondaire et n'est souvent important que pour les données littérales.
    Le fait que '²' se transforme en 'zz' après un chiffrage/déchiffrage tend à me faire penser que que l'entrée est en UTF8 (1 caractère donne 2) et que le chiffrage ne supporte pas l'UTF8 et sort un encodage monobyte (ascii, iso8859, ...). Mais là ce n'est qu'une supposition car tu ne donnes pas beaucoup de détails, comme qui développe quoi dans quel cadre quel environnement etc ...

Discussions similaires

  1. Soucis expressions régulières
    Par RTK45 dans le forum Applications et environnements graphiques
    Réponses: 4
    Dernier message: 16/02/2012, 23h19
  2. Réponses: 11
    Dernier message: 07/04/2010, 18h51
  3. [VB6-Expressions régulières]Petit souci
    Par loverdose dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 27/09/2006, 16h17
  4. Expressions réguliéres
    Par Tooms dans le forum Langage
    Réponses: 4
    Dernier message: 06/12/2002, 19h42
  5. Réponses: 5
    Dernier message: 11/06/2002, 16h21

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