Seite 1 von 1

regexp: alle matches für eine gruppe finden

Verfasst: Montag 24. September 2007, 00:12
von Jona
Abend Jungs,


ich habe vor jahren schonmal mit python rumgespielt und jetzt muss ich mal wieder etwas coden und habs wieder ausgekramt.
und bin auf dieses schöne forum gestossen. hallo :)


natürlich habe ich auch gleich ein problem :twisted:

ich nutze eine sehr unkomfortable sprache für die ich in python textersetzungsmakros schreiben will.

das wichtigste wäre erstmal eine art printf() zu haben.

Code: Alles auswählen

//ich würde also folgenden kommentar in den code schreiben
//MACRO:PRINTF("hello %I cruel %L world", 49, 11)

//der dann vom py-skript in dieses umgewandelt wird:
//den folgenden code könnt ihr ignorieren, aber wenn ihr mein leid wirklich nachvollziehen wollt ...

int printf_ints[1]; 
printf_ints[0] = 49;

long printf_longints[1]; 
printf_longints[0] = 11;

string printf_msg; 
printf_msg = "hello %I cruel %L world";

printf(printf_msg, printf_ints, printf_longints);

ich dachte man könnte jetzt einfach einen einzigen regexp ausdruck basteln:

Code: Alles auswählen

test_data = '//MACRO:PRINTF("hello %I cruel %L world",49,11)' 

p_full = re.compile('''
    //MACRO:PRINTF      # flag
    \("                 # arguments
        (
            [a-zA-Z ]+  # string
            |
            (?P<FMT_INT>%I)     # format int
            | 
            (?P<FMT_LONG>%L)    # format long
        )+                 
        ([, ]|(?P<ARG>[0-9]+))*   # comma separated (long)int arguments    
     "\)
     ''', re.VERBOSE)
und dann kommt man irgendwie an ein dictionary mit allen matches für alle benannten gruppen.
aber:
group( [group1, ...])
Returns one or more subgroups of the match. (...) If a group is contained in a part of the pattern that matched multiple times, the last match is returned.
komme ich nicht an eine liste mit allen matches für eine gruppe?
muss ich das also irgendwie folgendermaßen machen:

Code: Alles auswählen

>>> p_divide = re.compile('//MACRO:PRINTF\("(?P<STRING>.*?)"(?P<ARGS>[, 0-9]*)\)
>>> p_arg = re.compile("(?P<INT>%I)|(?P<LONG>%L)")
>>>
>>> m = p_divide.match('//MACRO:PRINTF("hello %I cruel %L wor %I ld",49,11,33)')
>>>
>>> s = m.group("STRING")
>>> m = p_arg.search(s)
>>> while m:
...     pos = m.start()
...     s = s[pos+1:]
...     print s[0]
...     m = p_arg.search(s)
...
I
L
I
das ist doch nicht schön :(

Verfasst: Montag 24. September 2007, 00:52
von poker
Hi, **was** für ein Zufall ;) => http://www.python-forum.de/topic-12040. ... hlight=24h

Kannst gleich mit ja abstimmen :D
muss ich das also irgendwie folgendermaßen machen:
Exakt.

Verfasst: Montag 24. September 2007, 06:04
von mitsuhiko
Das Beispiel ergibt keinen Sinn. Das kannst du nicht mit einer Regexp lösen weil (hoffe ich) die Position der Konstanten undefiniert ist. Wenn du wirklich einen Preprozessor schreiben willst kommst du an einem vollem Lexer nicht vorbei.

Verfasst: Montag 24. September 2007, 08:08
von Jona
wenn es möglich wäre eine geordnete liste von alle guppenmathces zu bekommen wäre das sehr wohl möglich.


'//MACRO:PRINTF("hello %I cruel %L world",49,11)'

wäre dann

[ [FMT_INT, %I], [FMT_LONG, %L], [ARG, 49], [ARG,11] ]

aber bei tageslicht betrachttet hast du natürlich recht.
das ist eigentlich keine aufgabe für regexp.


poker, deinen beitrag habe ich nicht beachtet (warum sollte das auch ein bug sein?) aber ich schaue mir mal das sre an...