2008-09-13 10 views
5

Ce qui suit est une expression régulière que j'ai écrite pour correspondre à des macros de pré-processeur multi-lignes en code C/C++. Je ne suis en aucun cas un gourou des expressions régulières, donc je serais heureux de recevoir des conseils sur la façon dont je peux améliorer cela.regex python correspondant à une macro de préprocesseur multi-lignes

Voici le regex:

\s*#define(.*\\\n)+[\S]+(?!\\) 

Il doit correspondre à tout cela:

#define foo(x) if(x) \ 
doSomething(x) 

Mais seulement une partie de cette (ne doit pas correspondre à la ligne de code suivante:

#define foo(x) if(x) \ 
doSomething(x) 
normalCode(); 

Et ne doit pas non plus correspondre à des macros de préprocesseur à ligne unique

Je suis assez sûr que l'expression régulière ci-dessus fonctionne - mais comme je l'ai dit, il y a probablement une meilleure façon de le faire, et j'imagine qu'il y a des façons de le casser. Quelqu'un peut-il suggérer?

Répondre

5

Ce programme de test simple, je frappais jusqu'à:

#!/usr/bin/env python 

TEST1=""" 
#include "Foo.h" 
#define bar foo\\ 
    x 
#include "Bar.h" 
""" 

TEST2=""" 
#define bar foo 
#define x 1 \\ 
    12 \\ 
    2 \\\\ 3 
Foobar 
""" 

TEST3=""" 
#define foo(x) if(x) \\ 
doSomething(x) 
""" 

TEST4=""" 
#define foo(x) if(x) \\ 
doSomething(x) 
normalCode(); 
""" 

import re 
matcher = re.compile(r"^[ \t]*#define(.*\\\n)+.*$",re.MULTILINE) 

def extractDefines(s): 
    mo = matcher.search(s) 
    if not mo: 
     print mo 
     return 
    print mo.group(0) 

extractDefines(TEST1) 
extractDefines(TEST2) 
extractDefines(TEST3) 
extractDefines(TEST4) 

La re je:

r"^[ \t]*#define(.*\\\n)+.*$" 

est très similaire à celui utilisé à partir, les modifications:

  1. [\ t] Pour éviter les retours à la ligne au début de la définir.
  2. Je compte sur + étant gourmand, donc je peux utiliser un simple. * $ À la fin pour obtenir la première ligne de la définir qui ne se termine pas avec \
4
start  = r"^\s*#define\s+" 
continuation = r"(?:.*\\\n)+" 
lastline  = r".*$" 

re_multiline_macros = re.compile(start + continuation + lastline, 
           re.MULTILINE) 
Questions connexes