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 :

extraire sous chaine à partir d'une regex ?


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Points : 40
    Points
    40
    Par défaut extraire sous chaine à partir d'une regex ?
    salut à tous,
    j'ai un probléme d'extraction de nom à partir d'un email.
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
     
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <regex.h>
     
    int main(void) {
       char *Chaine = NULL;
     
       regex_t MotifCompile;
       regmatch_t *TableauSousExpressions = NULL;
       const char *Motif = "^\\b([0-9A-Za-z_-]*)@{1}[0-9A-Za-z_-]{2,15}\\.[A-Za-z]{2,3}\\b$";
       char *MessageErreur = NULL;
       int ErreurRegex,LongeurMaxMsgErreur,NombresSousChaines,ErreurComparaison,LongueurSousChaine,Compteur;
     
     
       assert(Chaine == NULL);
       Chaine = (char*)malloc(256);
       if (Chaine == NULL) {
         perror("malloac");
         exit(1);
       }
     
       fgets(Chaine,256,stdin);
     
       ErreurRegex = regcomp(&MotifCompile,Motif,REG_EXTENDED | REG_NEWLINE);
       if (ErreurRegex != 0) {
         LongeurMaxMsgErreur = regerror(ErreurRegex,&MotifCompile,NULL,0);
         assert(MessageErreur == NULL);
         MessageErreur = (char*)malloc(LongeurMaxMsgErreur);
         if (MessageErreur == NULL) {
           perror("malloc");
           exit(1);
         }
         regerror(ErreurRegex,&MotifCompile,MessageErreur,LongeurMaxMsgErreur);
         fprintf(stderr,"Erreur : %s\n",MessageErreur);
     
         assert(MessageErreur != NULL);
         free(MessageErreur);
         MessageErreur = NULL;
         exit(1);
       }
       NombresSousChaines = MotifCompile.re_nsub + 1;
       fprintf(stdout,"Nombre sous chaînes  = %d\n",NombresSousChaines);
       assert(TableauSousExpressions == NULL);
       TableauSousExpressions = (regmatch_t*)malloc(NombresSousChaines*sizeof(regmatch_t));
       if (TableauSousExpressions == NULL) {
         perror("malloc");
         exit(1);
       }
       ErreurComparaison = regexec(&MotifCompile,Chaine,NombresSousChaines,TableauSousExpressions,REG_NOTEOL);
       if (ErreurComparaison == REG_ESPACE) {
         fprintf(stderr,"Erreur fatale\n");
         exit(1);
       }
       if (ErreurComparaison == REG_NOMATCH) {
         fprintf(stderr,"pas de correspondance.\n");
         exit(1);
       }
     
       for (Compteur = 0 ; Compteur < NombresSousChaines; Compteur++) {
         LongueurSousChaine = TableauSousExpressions[Compteur].rm_eo - TableauSousExpressions[Compteur].rm_so;
         fprintf (stdout,"Correspondance = %s\n",(char*) (Chaine+TableauSousExpressions[Compteur].rm_so));
       }
     
     
       assert(TableauSousExpressions != NULL);
       free(TableauSousExpressions);
       TableauSousExpressions = NULL;
       NombresSousChaines = 0;
       regfree(&MotifCompile);
     
       assert(Chaine != NULL);
       free(Chaine);
       Chaine = NULL;
     
       return(0);
    }
    ça donne :


    pourtant j'ai mémorisé la partie regex avec les parabthèses :
    ([0-9A-Za-z_-]*)
    merci d'avance


    je veux afficher :
    nom_prenom-266

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 109
    Points : 168
    Points
    168
    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
     
    #include <stdio.h>
     
    int main(void)
    {
      char name[128];
      char mail[] = "nom_prenom-266@domaine9-ent.org";
     
      sscanf(mail, "%127[^@]", name);
      puts(name);
      return 0;
    }

  3. #3
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Points : 40
    Points
    40
    Par défaut
    merci magma², mais c'est bizarre dans les tutu des regx tous parlent des paranthèses pour extraire une sous chaîne.
    Donc je ne peux pas les utilises, non ?

  4. #4
    Inactif  
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 123
    Points : 130
    Points
    130
    Par défaut regex
    Bonjour,
    Ahhhh...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "^\\b([0-9A-Za-z_-]*)@{1}[0-9A-Za-z_-]{2,15}\\.[A-Za-z]{2,3}\\b$";
    ton motif est erroné, c'est pour cela qu'il te retourne toute la chaîne.

  5. #5
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Points : 40
    Points
    40
    Par défaut
    je vois pas comment le corriger.
    Vous pouvez m'aider si'il vous plaît.

  6. #6
    Inactif  
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 123
    Points : 130
    Points
    130
    Par défaut solution
    Votre regexp est bonne en fait.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       for (Compteur = 0 ; Compteur < NombresSousChaines; Compteur++) {
         LongueurSousChaine = TableauSousExpressions[Compteur].rm_eo - TableauSousExpressions[Compteur].rm_so;
         fprintf (stdout,"Correspondance = %s\n",(char*) (Chaine+TableauSousExpressions[Compteur].rm_so));
       }
    C'est juste ce petit bout de code, qui affiche toute la chaîne à partir de rm_so.
    il vous faut faire comme sur regexec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    fprintf(stdout, "Correspondance = %.*s\n", TableauSousExpressions[Compteur].rm_eo - TableauSousExpressions[Compteur].rm_so, &Chaine[TableauSousExpressions[Compteur].rm_so]);

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 26
    Points : 37
    Points
    37
    Par défaut
    Citation Envoyé par magma² Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
     
    int main(void)
    {
      char name[128];
      char mail[] = "nom_prenom-266@domaine9-ent.org";
     
      sscanf(mail, "%127[^@]", name);
      puts(name);
      return 0;
    }
    Bonjour. Ce procédé est certes pratique mais ne fonctionnera pas si le nom d'utilisateur possède un @ précédé d'un antislash, par exemple : pr\@bleme@host.tld

    En fait, la regex proposé par le PO posera aussi problème dans le cas où la première partie de l'adresse comporte un point par exemple.

    Voici la regex supposé correspondre à toutes les adresses conformes à la norme (RFC 2822) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
    Vous pourrez en l'utilisant capturer la partie que vous rechercher.

  8. #8
    Inactif  
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    123
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 123
    Points : 130
    Points
    130
    Par défaut
    Citation Envoyé par Zebrure Voir le message
    Voici la regex supposé correspondre à toutes les adresses conformes à la norme (RFC 2822) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
    Bon à savoir ça, Merci

  9. #9
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Points : 40
    Points
    40
    Par défaut
    merci pour vos interventions. merci à tous.

  10. #10
    Membre du Club
    Inscrit en
    Mars 2006
    Messages
    94
    Détails du profil
    Informations forums :
    Inscription : Mars 2006
    Messages : 94
    Points : 40
    Points
    40
    Par défaut
    il fallait juste ajouter le byte nul à la fin des chaînes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for (Compteur = 0 ; Compteur < NombresSousChaines; Compteur++) { 
         strcpy(Chaine1,Chaine+TableauSousExpressions[Compteur].rm_so);
         Chaine1[TableauSousExpressions[Compteur].rm_eo] = '\0';
        fprintf(stdout, "Correspondance = %s\n", Chaine1);
       }
    merci les gars, j'ai appris deux nouveaux truc grâces à vos réponses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sscanf(mail, "%127[^@]", name);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fprintf(stdout, "Correspondance = %.*s\n", TableauSousExpressions[Compteur].rm_eo - TableauSousExpressions[Compteur].rm_so, &Chaine[TableauSousExpressions[Compteur].rm_so]);
    merci

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

Discussions similaires

  1. extraire sous chaine avec regex
    Par reg01 dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 28/06/2010, 18h39
  2. Extraction d'une sous-chaine à partir d'une chaine principale
    Par gazere dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 13/06/2007, 05h08
  3. Réponses: 1
    Dernier message: 18/04/2007, 18h07
  4. Réponses: 3
    Dernier message: 17/04/2007, 16h58
  5. extraire des mots à partir d'une chaine
    Par freestyler dans le forum Delphi
    Réponses: 5
    Dernier message: 28/09/2006, 16h04

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