[Python-de] Gruppen in sich wiederholenden Sub-Patterns

Stefan Schwarzer sschwarzer at sschwarzer.net
Do Nov 15 16:59:31 EST 2018


Hallo,

ich bin gerade auf etwas gestoßen, das mich ziemlich
überrascht hat:

In [22]: import re

In [23]: regex = re.compile(r"""
    ...: ( \( \w+ , \w+ \) )
    ...: (?:
    ...:   , ( \( \w+ , \w+ \) )
    ...: )*  # beliebige Anzahl von Wiederholungen!
    ...: """, re.VERBOSE)

Hier geht es darum, in einem String alle durch Kommas getrennte
Gruppen der Form '(ab,cd)' zu finden. (`\w+` kann natürlich mehr
matchen, aber das sollte hier keinen Unterschied machen.)

Das Folgende funktioniert noch wie erwartet:

In [24]: regex.search('(ab,cd),(ef,gh)').groups()
Out[24]: ('(ab,cd)', '(ef,gh)')

Aber das hat mich überrascht:

In [25]: regex.search('(ab,cd),(ef,gh),(ij,kl)').groups()
Out[25]: ('(ab,cd)', '(ij,kl)')

In [26]: regex.search('(ab,cd),(ef,gh),(ij,kl),(mn,op)').groups()
Out[26]: ('(ab,cd)', '(mn,op)')

Anscheinend findet sich im Match immer nur die letzte Gruppe
aus dem mit `*` wiederholten Sub-Pattern.

_Erwartet_ hatte ich (aber _nicht_ bekommen!):

In [25]: regex.search('(ab,cd),(ef,gh),(ij,kl)').groups()
Out[25]: ('(ab,cd)', '(ef,gh)', '(ij,kl)')

In [26]: regex.search('(ab,cd),(ef,gh),(ij,kl),(mn,op)').groups()
Out[26]: ('(ab,cd)', '(ef,gh)', '(ij,kl)', '(mn,op)')

Kann man erklären, warum sich der Match anders als erwartet
verhält (ohne nur das zu wiederholen, was ich schon gesagt
habe ;-) )?

Gibt es eine Möglichkeit, den regulären Ausdruck so umzuschreiben,
dass ich alle gewünschten Gruppen bekomme?

Falls nicht, wie würdet ihr das Problem sonst lösen? Mir sind
mögliche Ansätze eingefallen, aber die wirken alle ziemlich
frickelig.

Viele Grüße
Stefan


Mehr Informationen über die Mailingliste python-de