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 :

Utilisation de regex.h


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Points : 71
    Points
    71
    Par défaut Utilisation de regex.h
    Bonjour,

    j'aimerai utiliser les regex en C et je me suis vite tourner vers la librairie regex.h. J'ai créé un petit code de test :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    #include <stdio.h>
    #include <regex.h>
     
    int
    regex_string_check(const char *string)
    {
       const char *pattern = "[:alnum:]";
       regex_t regex;
       int ret;
     
       ret = regcomp(&regex, pattern, 0);
       if(ret != 0) return 1;
     
       ret = regexec(&regex, string, 0, NULL, 0);
       if(ret != 0) goto free_regex;
     
       regfree(&regex);
     
       return 0;
     
    free_regex:
       regfree(&regex);
       return 2;
    }
     
    int
    main(int argc, char **argv)
    {
       printf("Regex return : %d\n", regex_string_check("tot 14o"));
       printf("Regex return : %d\n", regex_string_check("tototata14"));
       printf("Regex return : %d\n", regex_string_check("toto @_-|yu"));
    }
    J'ai ma fonction "regex_string_check" qui me renvoie :
    * 0 si tout s'est passé,
    * 1 s'il n'a pas réussi à initialiser la regex,
    * 2 si la chaîne que je passe en paramètre ne correspond pas à ma regex.

    La regex que j'utilise est assez simple : "[:alnum:]" => je veux seulement les caractères alpha-numériques [a-zA-Z0-9].
    Logiquement il y a que la deuxième chaîne : "tototata14" qui devrait me renvoyer 0. La première contenant un espace et la deuxième des caractères non alpha-numérique.

    Or, voici le résultat de l'exécution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [root@bsd_dev ~/tests/c/regex]# ./regex
    Regex return : 2
    Regex return : 0
    Regex return : 0
    Je dois avoir un souci quelque part mais je vois pas où ?
    regcomp : regcomp returns 0 if it succeeds in compiling the regular expression; otherwise, it returns a nonzero error code (see the table below).
    regexec : regexec returns 0 if the regular expression matches; otherwise, it returns a nonzero value.

    Cordialement.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Bonjour,

    • Il faut écrire « [[:alnum:]] ». La première paire de crochets est le conteneur de caractères proprement dit, et les noms de classes sont ensuite passés à l'intérieur de celui-ci entre « [: » et « :] ». Ça te permet de spécifier éventuellement plusieurs classes ;
    • Garde à l'esprit que cette expression ne reconnaîtra que le premier caractère de la chaîne examinée et validant l'expression. Il faudra ajouter « * » ou « + » à ton expression si tu veux reconnaître un mot entier ;
    • Il manque un « return 0 » à la fin de ta fonction main ;
    • Prend l'habitude de ne jamais travailler en root sur ta machine. Crée un utilisateur propre auquel tu donneras des pouvoirs éventuellement.

  3. #3
    Membre régulier
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Points : 71
    Points
    71
    Par défaut
    Merci pour les informations

    Voici mon nouveau code :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <stdio.h>
    #include <regex.h>
     
    int
    regex_string_check(const char *string)
    {
       const char *pattern = "[^[:alnum:][:blank:]*$]";
       regex_t regex;
       int ret;
     
       ret = regcomp(&regex, pattern, 0);
       if(ret != 0) return 1;
     
       ret = regexec(&regex, string, 0, 0, 0);
       if(ret != 0) goto free_regex;
     
       regfree(&regex);
     
       return 0;
     
    free_regex:
       regfree(&regex);
       return 2;
    }
     
    int
    main(int argc, char **argv)
    {
       printf("Regex return : %d\n", regex_string_check("tot 14o"));
       printf("Regex return : %d\n", regex_string_check("tototata14"));
       printf("Regex return : %d\n", regex_string_check("toto @_-|yu"));
     
       return 0;
    }
    Pour autoriser les espaces, j'ai trouvé [:space:] mais d'après ce que je peux voir dans la documentation ça autorise aussi les tabulations. Est ce que l'on peut autoriser uniquement les espaces ?
    Voici le résultat de l'exécution (je suis toujours en root ^_^') :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    [root@bsd_dev ~/tests/c/regex]# ./regex
    Regex return : 2
    Regex return : 2
    Regex return : 0
    Le seul truc qui me perturbe c'est que les deux premières qui devraient fonctionner retournent 2 alors que la dernière qui ne devrait pas fonctionner retourne 0. C'est logique mais inversé O_o

    Edit : j'ai essayé de check l'erreur pour avoir plus d'information voici le code :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    int
    regex_string_check(const char *string)
    {
       const char *pattern = "[^[:alnum:][:blank:]*$]";
       regex_t regex;
       int ret;
     
       ret = regcomp(&regex, pattern, 0);
       if(ret != 0) return 1;
     
       ret = regexec(&regex, string, 0, 0, 0);
       if(ret)
         {
            if(ret == REG_NOMATCH) printf("No match !\n");
            else if(ret == REG_ESPACE) printf("Out of memory !\n");
            else printf("Error ! \n");
            goto free_regex;
         }
     
       regfree(&regex);
     
       return 0;
     
    free_regex:
       regfree(&regex);
       return 2;
    }
    Et dans la console il m'affiche "No match !" pour les deux premières expressions...

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    Citation Envoyé par Sango64 Voir le message
    Pour autoriser les espaces, j'ai trouvé [:space:] mais d'après ce que je peux voir dans la documentation ça autorise aussi les tabulations. Est ce que l'on peut autoriser uniquement les espaces ?
    Oui, il suffit de taper l'espace, comme un caractère ordinaire, plutôt qu'utiliser une classe de caractères.

    Le seul truc qui me perturbe c'est que les deux premières qui devraient fonctionner retournent 2 alors que la dernière qui ne devrait pas fonctionner retourne 0. C'est logique mais inversé O_o
    C'est normal, tu as ajouté « ^ » au début de ton motif, ce qui correspond à un négateur : à présent, l'expression recherche les caractères qui ne sont pas dans la liste.

    D'autre part, tu as ajouté « *$ » à la fin de ta liste mais à cet endroit, ils sont considérés comme des caractères ordinaires. Si ce sont les opérateurs dont on parlait plus haut, il faut les mettre en dehors des crochets.

    Et dans la console il m'affiche "No match !" pour les deux premières expressions...
    « No match » signifie « pas de correspondance ».

  5. #5
    Membre régulier
    Profil pro
    aucun
    Inscrit en
    Octobre 2009
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2009
    Messages : 98
    Points : 71
    Points
    71
    Par défaut
    Je suis vraiment un débutant en regex
    Je sais maintenant que '^' possède deux significations différentes selon son placement !

    Voici donc le fameux pattern qu'il me fallait : const char *pattern = "^[[:alnum:] ]*$";

    Merci encore pour tes conseils

  6. #6
    Invité
    Invité(e)
    Par défaut
    Petite intervention au passage pour présenter un site très intéressant pour tester des regex : https://regex101.com/

    Rappels des conventions utilisé pour les regex, et tests en temps réel d'un regex sur plusieurs chaîne de caractère différente.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 10/04/2007, 11h46
  2. utilisation de regex
    Par mhamedbj dans le forum Langage
    Réponses: 4
    Dernier message: 27/03/2007, 17h44
  3. utiliser un regex?
    Par Weedo dans le forum Langage
    Réponses: 3
    Dernier message: 10/01/2006, 17h38
  4. Réponses: 9
    Dernier message: 30/11/2005, 18h18
  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