Dans des expressions rationnelles élaborées, on peut trouver des sous-groupes :
Seulement, quand l'expression devient complexe, il est plus délicat de s'en sortir avec seulement les numéros des sous-groupes, qui peuvent être nombreux.
Il devient alors intéressant de donner un nom aux sous-groupes, pour les identifier. En Python, on peut faire cela comme suit :
(?:...)
Une première application de ce qui précède consiste à donner un nom vide à un sous-groupe, comme suit :
(?:...)
Cela peut avoir son utilité, quand un sous-groupe est clairement identifiable dans la chaîne, mais que son contenu n'a aucune importance : commentaires, etc.
Voici un exemple :
>>> m = re.match("([abc])+", "abc") >>> m.groups() ('c',) >>> m = re.match("(?:[abc])+", "abc") >>> m.groups() ()
Cette technique peut aussi s'avérer utile quand on doit rajouter un sous-groupe à une expression rationnelle, mais que l'on ne souhaite pas modifier la numérotation des sous-groupes.
La deuxième utilisation de cette syntaxe, nommer des sous-groupes, est plus intéressante. Elle permet de faire référence à ces sous-groupes.
Ainsi, chaque méthode de la classe MatchObject, comme group(), accepte ces noms en argument :
>>> p = re.compile(r'(?P<word>\b\w+\b)') >>> m = p.search( '(((( Lots of punctuation )))' ) >>> m.group('word') 'Lots' >>> m.group(1) 'Lots'
On constate, dans l'exemple ci-dessus, qu'un sous-groupe nommé possède encore son indice dans la numérotation des sous-groupes, ce qui peut s'avérer utile.
Voici un exemple qui montre combien nommer des sous-groupes peut servir :
>>> InternalDate = re.compile(r'INTERNALDATE "' ... r'(?P<jour>[ 123][0-9])-(?P<mois>[A-Z][a-z][a-z])-' ... r'(?P<annee>[0-9][0-9][0-9][0-9])' ... r' (?P<heure>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])' ... r' (?P<zone>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])' ... r'"')
Il est clairement plus aisé de faire appel à m.group('zone'), plutôt qu'à m.group(9)...
On sait qu'il est possible de faire référence au contenu du iième sous-groupe avec \i.
On peut de même utiliser le nom d'un sous-groupe nommé, pour faire référence à son contenu dans une expression rationnelle, comme suit :
(?P=name)
où name est le nom du sous-groupe considéré.
Reprenons par exemple le problème consistant à chercher les mots qui se répètent, à la suite, dans un texte. L'expression rationnelle correspondante était
(\b\w+)\s+\1
Cette expression peut aussi s'écrire ainsi :
(?P<mot>\b\w+)\s+(?P=mot)
La preuve...
>>> p = re.compile(r'(?P<mot>\b\w+)\s+(?P=mot)') >>> p.search('Paris in the the spring').group() 'the the'