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 :

les expressions régulières


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 45
    Par défaut les expressions régulières
    Bonjour

    Je dois traduire ce bout de code en C ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    if ($cmctext =~ /.*unit\dMsgIndex\.\d\s=\sINTEGER:\s(\d).*unit\dMsgText\.\d\*s=\sSTRING:(.*)Marque.*unit\dMsgStatus\.\d\s=\sINTEGER:\s(.**)/)
    {
    	my $Int = $1;
    	my $Title = $2;
    	my $Val = $3;
    	if ($Int == 3 && $Title =~ /test/ && $Val =~ /ok/)
    	{
    		return 1;
    	}				
    }
    Il y a une expression régulière...
    Comment faire en C?

    J'ai commencé comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    char *Title;
    char *Val;
    int Int;
     
    if(sscanf (message, "/.*unit\dMsgIndex\.\d\s=\sINTEGER:\s(\d).*unit\dMsgText\.\d\s=\sSTRING:(.*)RITTAL.*unit\dMsgStatus\.\d\s=\sINTEGER:\s(.*)/", &Int , &Title, &Val  ) == 1)
    {
     //code
    }
    Déjà, mon expression régulière est mal traduite... car je l'ai repris du perl


    Quelqu'un sait-il comment coder ça en C ?




    Merci d'avance

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Pour une expression régulière, oublie scanf() et compagnie.

    Les points d'entrée en C, c'est regcomp(), regexec, regerror() et regfree() ici
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 45
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    Pour une expression régulière, oublie scanf() et compagnie.

    Les points d'entrée en C, c'est regcomp(), regexec, regerror() et regfree() ici

    Bonjour,

    merci pour la réponse

    Est-ce qu'il y aurait des exemples concrets utilisant ces fonctions?
    car ça ne me parle guère...



    edit:
    j'ai trouvé ceci via le site:
    http://nicolasj.developpez.com/articles/regex/

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 45
    Par défaut
    Suite à l'exemple, trouvé, j'arrive à comparer ma chaine et à en déduire si elle est exacte ou non.

    Mais j'aimerais sauvegarder des parties de la chaine dans des variables :s je coince
    Je pensais utiliser sscanf mais on me le déconseille...

    voilà l'adaptation de l'exemple:
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <regex.h>
     
    int main (void)
    {
       int err;
       regex_t preg;
       const char *str_request = "IBM-SELVENDE::portablecomputer2Msg.2.1.1.3 = INTEGER: 3  portablecomputerUnit2Msg.2.1.2.3 = STRING: \"Exemple 2\"	IBM-SELVENDE::";
     
       const char *str_regex = "\\.*portablecomputer[1-9]Msg\\.[1-9]\\.[1-9]\\.2\\.[1-9][[:space:]]+=[[:space:]]+STRING:[[:space:]]\\.*";
     
     
    /* (1) */
       err = regcomp (&preg, str_regex, REG_NOSUB | REG_EXTENDED);
       if (err == 0)
       {
          int match;
     
    /* (2) */
          match = regexec (&preg, str_request, 0, NULL, 0);
    /* (3) */
          regfree (&preg);
    /* (4) */
          if (match == 0)
          {
             printf ("\n%s \nest un message valide\n", str_request);
          }
    /* (5) */
          else if (match == REG_NOMATCH)
          {
             printf ("\n%s \n n\'est pas un message valide\n", str_request);
          }
    /* (6) */
          else
          {
             char *text;
             size_t size;
     
    /* (7) */
             size = regerror (err, &preg, NULL, 0);
             text = malloc (sizeof (*text) * size);
             if (text)
             {
    /* (8) */
                regerror (err, &preg, text, size);
                fprintf (stderr, "%s\n", text);
                free (text);
             }
             else
             {
                fprintf (stderr, "Memoire insuffisante\n");
                exit (EXIT_FAILURE);
             }
          }
       }
       puts ("\nPressez une touche pour continuer\n");
     
       getchar ();
       return (EXIT_SUCCESS);
    }
    j'aimerais récupérer dans une variable ce qi se trouve entre " " après STRING

    Avec quelle fonction est-ce possible?
    Peut-être avec l'attribut REG_NOSUB mais je ne vois pas comment l'utiliser en lisant la doc...


    Merci d'avance

  5. #5
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Il faut que tu changes plusieurs choses :

    - Il ne faut pas utiliser REG_NOSUB pour regcomp (ça sert justement à dire que tu ne veux pas extraire les sous-expressions)

    - En 4ème argument de regexec, tu dois passer un tableau de regmatch_t. En 3ème argument, tu passes le nombre d'éléments du tableau. C'est dans se tableau que te sont retournées les sous-expressions. Si tu veux extraire N sous-expressions, il faut passer un tableau de N+1 éléments (l'élément 0 est la chaine qui match l'expression entirère, l'élément 1 est la chaine qui match la première sous-expression, etc)

    - Pour extraire la chaine qui a matché la sous-expression n, tu regarde le nième élément de ton tableau de regmatch_t. Cette strucute a deux champs, rm_so et rm_eo, qui sont les indices de début et de fin de la partie de ta chaine d'origine qui match la sous-expression.

    Lit la doc pour plus d'infos, tout est expliqué.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2006
    Messages : 45
    Par défaut
    Citation Envoyé par matafan Voir le message
    Il faut que tu changes plusieurs choses :

    - Il ne faut pas utiliser REG_NOSUB pour regcomp (ça sert justement à dire que tu ne veux pas extraire les sous-expressions)

    - En 4ème argument de regexec, tu dois passer un tableau de regmatch_t. En 3ème argument, tu passes le nombre d'éléments du tableau. C'est dans se tableau que te sont retournées les sous-expressions. Si tu veux extraire N sous-expressions, il faut passer un tableau de N+1 éléments (l'élément 0 est la chaine qui match l'expression entirère, l'élément 1 est la chaine qui match la première sous-expression, etc)

    - Pour extraire la chaine qui a matché la sous-expression n, tu regarde le nième élément de ton tableau de regmatch_t. Cette strucute a deux champs, rm_so et rm_eo, qui sont les indices de début et de fin de la partie de ta chaine d'origine qui match la sous-expression.

    Lit la doc pour plus d'infos, tout est expliqué.

    J'ai utilisé l'exemple pour arriver à ce que vous expliquez avec mes expressions régulières
    voilà 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
    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
    81
    82
    83
    84
    85
    86
    87
    88
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <regex.h>
     
    int main (void)
    {
       int err;
       regex_t preg;
     
       const char *str_request = "PORTABLE-IBM-TC-AXE::tdbfffStatusParse2Msg.2.1.1.3 = INTEGER: 3  tdbfffStatusParse2Msg.2.1.2.3 = STRING: \"www.developpez.net\"	PORTABLE-IBM-TC-AXE::";
    	const char *str_regex = "\\.*tdbfffStatusParse[1-9]Msg\\.[1-9]\\.[1-9]\\.2\\.[1-9][[:space:]]+=[[:space:]]+STRING:[[:space:]]+\\.*\"(www\\.[-_[:alnum:]]+\\.[[:lower:]]{2,4})\"\\.*";
     
     
     
    /* (1) */
       err = regcomp (&preg, str_regex, REG_EXTENDED);
       if (err == 0)
       {
          int match;
          size_t nmatch = 0;
          regmatch_t *pmatch = NULL;
     
          nmatch = preg.re_nsub;
          pmatch = malloc (sizeof (*pmatch) * nmatch);
          if (pmatch)
          {
    /* (2) */
             match = regexec (&preg, str_request, nmatch, pmatch, 0);
    /* (3) */
             regfree (&preg);
    /* (4) */
             if (match == 0)
             {
                char *site = NULL;
                int start = pmatch[0].rm_so;
                int end = pmatch[0].rm_eo;
                size_t size = end - start;
     
                site = malloc (sizeof (*site) * (size + 1));
                if (site)
                {
                   strncpy (site, &str_request[start], size);
                   site[size] = '\0';
    			   printf ("\ntest: %s\n", site);
                   free (site);
                }
             }
    /* (5) */
             else if (match == REG_NOMATCH)
             {
                printf ("%s n\'est pas une adresse internet valide\n", str_request);
             }
    /* (6) */
             else
             {
                char *text;
                size_t size;
     
    /* (7) */
                size = regerror (err, &preg, NULL, 0);
                text = malloc (sizeof (*text) * size);
                if (text)
                {
    /* (8) */
                   regerror (err, &preg, text, size);
                   fprintf (stderr, "%s\n", text);
                   free (text);
                }
                else
                {
                   fprintf (stderr, "Memoire insuffisante\n");
                   exit (EXIT_FAILURE);
                }
             }
          }
          else
          {
             fprintf (stderr, "Memoire insuffisante\n");
             exit (EXIT_FAILURE);
          }
       }
       puts ("\nPress enter\n");
    /* Dev-cpp */
       getchar ();
       return (EXIT_SUCCESS);
    }
    il me renvoie:
    test: tdbfffStatusParse2Msg.2.1.2.3 = STRING: "www.developpez.net"
    Il faut qu'il me renvoie seulement: www.developpez.net

    J'ai joué avec les éléments du tableau pmatch mais je n'obtiens pas la réponse souhaité :s

    Pourriez-vous m'éclairer?
    faut-il absolument une expression du type(
    const char *str_regex = "\\.*\"(www\\.[-_[:alnum:]]+\\.[[:lower:]]{2,4})\"\\.*"; ) ?

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

Discussions similaires

  1. [VB.net][vs2005] Problème avec les expressions régulières
    Par zouhib dans le forum Windows Forms
    Réponses: 13
    Dernier message: 22/06/2006, 15h56
  2. Problème avec les expressions régulières
    Par Premium dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 18/06/2006, 16h41
  3. Les Expressions Régulières
    Par zEndymion dans le forum Access
    Réponses: 4
    Dernier message: 12/06/2006, 13h36

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