web-dev-qa-db-fra.com

expressions rationnelles: comment accéder à plusieurs correspondances d'un groupe?

Je rassemble une expression régulière assez complexe. Une partie de l'expression correspond à des chaînes telles que "+ a", "-57", etc. A + ou a - suivi d'un nombre quelconque de lettres ou de chiffres. Je veux faire correspondre 0 ou plusieurs chaînes correspondant à ce modèle.

C'est l'expression que j'ai trouvée:

([\+-][a-zA-Z0-9]+)*

Si je devais rechercher la chaîne '-56 + a' en utilisant ce modèle, je m'attendrais à obtenir deux correspondances:

+ a et -56

Cependant, je ne reçois que le dernier match:

>>> m = re.match("([\+-][a-zA-Z0-9]+)*", '-56+a')
>>> m.groups()
('+a',)

En regardant les documents python je vois que:

Si un groupe correspond plusieurs fois, seule la dernière correspondance est accessible:

>>> m = re.match(r"(..)+", "a1b2c3")  # Matches 3 times.
>>> m.group(1)                        # Returns only the last match.
'c3'

Donc, ma question est: comment do vous accédez à plusieurs correspondances de groupe?

60
Tom Scrace

Supprimez le * De votre expression régulière (pour qu'il corresponde exactement à une instance de votre modèle). Utilisez ensuite re.findall(...) ou re.finditer (Voir ici ) pour renvoyer toutes les correspondances.

Mise à jour:

Il semble que vous construisiez essentiellement un analyseur de descente récursif . Pour les tâches d'analyse relativement simples, il est assez courant et tout à fait raisonnable de le faire à la main. Si vous êtes intéressé par une solution de bibliothèque (au cas où votre tâche d'analyse pourrait devenir plus compliquée plus tard, par exemple), jetez un œil à pyparsing .

57
phooji

Le module regex corrige cela, en ajoutant un .captures méthode:

>>> m = regex.match(r"(..)+", "a1b2c3")
>>> m.captures(1)
['a1', 'b2', 'c3']
27
Eric