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

Python Discussion :

Une expression régulière récalcitrante


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut Une expression régulière récalcitrante
    Bonjour,

    je cherche à faire un petit parseur de code C qui retrouve les prototypes des fonctions.

    Je me suis fait le code suivant :
    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
    def findall ( exp,str ):
        '''Renvoie une liste de dict de toutes les occurrences de exp dans la chaîne str 
           (re.findall ne fait pas ce que je veux)'''
        res,pos = [],0
        while True :
            match = exp.search( str[pos:],re.DOTALL )
            if not match : return res
            pos += match.end()-1
            res += [ match.groupdict() ]
     
    def find_all_proto ( source ):
        '''Renvoie tous les prototypes C de source'''
        regx = r'''(\W|\A)
                   (?P<type>  (\w+ ( \* | \s+ )+ )+  )
                   (?P<name>  \w+  )
                   \s*\(
                   (?P<param> .*? )
                   \) \s* ;'''
        ex_proto = re.compile( regx,re.DOTALL+re.VERBOSE)
        return findall( ex_proto,source ) 
     
    def test_find_proto ():
        s = '''void f1 ();
               void f2 ( void ) ; 
               void f3( int x );void f4 ( int x , char * s ); 
               void*f5 ( int x , char * s ); 
               void* f6 ( int x , char * s ); 
               void *f7 ( int x , char * s ); 
               void * f8 ( int x , char * s ); 
               int ** f9 ( int x , char * s ); 
               int * * f10 ( int x , char * s ); 
               int * ** f11 ( int x , char * s ); 
               const int * ** f12 ( int x , char * s ); 
               const int*const **f13 ( int x , char * s ); 
               const int f14 ( int x , char * s ); 
               static const int f15 ( int x , char * s ); 
            '''
        for p in find_all_proto( s ):
            print '%-20s : %3s : %s'%(p.get('type'),p.get('name'),p.get('param',''))
     
    test_find_proto()
    et j'obtiens ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void                 :  f2 :  void 
    void                 :  f4 :  int x , char * s 
    void*                :  f6 :  int x , char * s 
    void *               :  f8 :  int x , char * s 
    int * *              : f10 :  int x , char * s 
    const int * **       : f12 :  int x , char * s 
    int*const **         : f13 :  int x , char * s 
    int                  : f14 :  int x , char * s 
    const int            : f15 :  int x , char * s
    Comme vous pouvez le voir il me manque presque une fonction sur 2, à part les 13 et 15 dont il manque le premier mot.
    Si je supprime la fin de l'expression régulière
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        regx = r'''(\W|\A)
                   (?P<type>  (\w+ ( \* | \s+ )+ )+  )
                   (?P<name>  \w+  )
                   \s*\('''
    j'obtiens ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void                 :  f2 : 
    void                 :  f3 : 
    void*                :  f5 : 
    void*                :  f6 : 
    void *               :  f7 : 
    void *               :  f8 : 
    int **               :  f9 : 
    int * *              : f10 : 
    int * **             : f11 : 
    const int * **       : f12 : 
    const int*const **   : f13 : 
    const int            : f14 : 
    static const int     : f15 :
    Cette fois, j'ai bien toutes les fonctions et il ne manque aucun mot.
    A part "f1" et "f4" qui manquent encore.

    Donc, à vous les experts des reg exp : comment expliquer un tel comportement ?

    Encore plus étrange :
    Si j'ajoute une première ligne à mes prototypes de test, le résultat dépend du nombre de caractères :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def test_find_proto ():
        s = '''zzzzz
               void f1 ();
               ....
    j'ai bien "f1" mais je perds "f2" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void                 :  f1 : 
    void                 :  f3 : 
    void*                :  f5 : 
    void*                :  f6 : 
    void *               :  f7 : 
    void *               :  f8 : 
    ...
    Mais avec un 'z' de moins, je pers à nouveau "f1".

    Si quelqu'un a une idée... moi je suis à sec !

    Merci !

  2. #2
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Bah, j’ai fini par trouver…

    Ton problème, c’est le re.DOTALL de exp.search, dans findall*! Vire-le*!

    La signature de la search d’une regex compilée n’est pas la même que celle de la search du module!

    Pour une regex compilée, c’est regex.search(string[, pos[, endpos]])… Ça se passe de commentaire, amha.

  3. #3
    Membre éclairé
    Avatar de Captain'Flam
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2011
    Messages
    273
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 273
    Billets dans le blog
    1
    Par défaut
    Argl ! je m'acharnais sur la syntaxe de ma regexp...



    merci !

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

Discussions similaires

  1. [EXP] Evaluation dans une expression régulière
    Par SergentHeinz dans le forum Langage
    Réponses: 7
    Dernier message: 10/11/2005, 18h17
  2. Une expression réguliére
    Par BRAUKRIS dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 09/09/2005, 20h14
  3. Réponses: 6
    Dernier message: 17/08/2005, 12h38
  4. Problème sur une expression régulière
    Par Verbal-Quint dans le forum Langage
    Réponses: 6
    Dernier message: 12/11/2004, 10h54
  5. [Regex] Vérifier qu'une chaîne respecte une expression régulière
    Par PeteMitchell dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 13/05/2004, 14h22

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