Regexes en Python (Partie 2) – Real Python

By | juin 3, 2020

Python pas cher

Comme vous l’avez vu, la plupart des fonctions et méthodes du module retourner un faire correspondre l'objet en cas de match réussi. Parce qu'un objet de correspondance est véridique, vous pouvez l'utiliser dans une condition:

Mais les objets de correspondance contiennent également un certain nombre d'informations utiles sur la correspondance. Vous en avez déjà vu une partie – le span = et match = données que l'interpréteur affiche lorsqu'il affiche un objet de correspondance. Vous pouvez obtenir beaucoup plus d'un objet match en utilisant ses méthodes et attributs.

Méthodes d'objet de correspondance

Le tableau ci-dessous résume les méthodes disponibles pour un objet de correspondance rencontre:

Méthode Retour
match.group () Le ou les groupes capturés spécifiés de rencontre
match .__ getitem __ () Un groupe capturé de rencontre
match.groups () Tous les groupes capturés de rencontre
match.groupdict () Un dictionnaire des groupes capturés nommés de rencontre
match.expand () Le résultat de la substitution de références rencontre
match.start () L'index de départ de rencontre
match.end () L'indice final de rencontre
match.span () Les indices de départ et de fin de rencontre comme un tuple

Les sections suivantes décrivent ces méthodes plus en détail.

match.group ([[[[, ...])

Renvoie le ou les groupes capturés spécifiés à partir d'une correspondance.

Pour les groupes numérotés, match.group (n) renvoie le ne groupe:

>>>

>>> m = .chercher(r«( w +), ( w +), ( w +)», 'foo, bar, baz')
>>> m.groupe(1)
'foo'
>>> m.groupe(3)
«baz»

Si vous capturez des groupes à l'aide (? P), puis match.group () renvoie le groupe nommé correspondant:

>>>

>>> m = .rencontre(r«(? P w +), (? P w +), (? P w +) ', «quux, corge, grault»)
>>> m.groupe(«w1»)
«quux»
>>> m.groupe(«w3»)
«grault»

Avec plus d'un argument, .groupe() renvoie un tuple de tous les groupes spécifiés. Un groupe donné peut apparaître plusieurs fois et vous pouvez spécifier n'importe quel groupe capturé dans n'importe quel ordre:

>>>

>>> m = .chercher(r«( w +), ( w +), ( w +)», 'foo, bar, baz')
>>> m.groupe(1, 3)
('foo', 'baz')
>>> m.groupe(3, 3, 1, 1, 2, 2)
('baz', 'baz', 'foo', 'foo', 'bar', 'bar')

>>> m = .rencontre(r«(? P w +), (? P w +), (? P w +) ', «quux, corge, grault»)
>>> m.groupe(«w3», «w1», «w1», «w2»)
('grault', 'quux', 'quux', 'corge')

Si vous spécifiez un groupe hors de portée ou inexistant, .groupe() soulève un IndexError exception:

>>>

>>> m = .chercher(r«( w +), ( w +), ( w +)», 'foo, bar, baz')
>>> m.groupe(4)
Traceback (dernier appel le plus récent):
  Fichier "", ligne 1, dans 
IndexError: pas un tel groupe

>>> m = .rencontre(r«(? P w +), (? P w +), (? P w +) ', «quux, corge, grault»)
>>> m.groupe('foo')
Traceback (dernier appel le plus récent):
  Fichier "", ligne 1, dans 
IndexError: pas un tel groupe

Il est possible pour une expression régulière en Python de correspondre dans son ensemble mais de contenir un groupe qui ne participe pas au match. Dans ce cas, .groupe() Retour Aucun pour le groupe non participant. Considérez cet exemple:

>>>

>>> m = .chercher(r'( w +), ( w +), ( w +)?', 'foo, bar,')
>>> m
<_sre.SRE_Match object; span=(0, 8), match='foo,bar,'>
>>> m.groupe(1, 2)
('foo', 'bar')

Cette expression régulière correspond, comme vous pouvez le voir sur l'objet de correspondance. Les deux premiers groupes capturés contiennent 'foo' et 'bar', respectivement.

Un point d'interrogation (?), le métacaractère quantificateur suit le troisième groupe, de sorte que ce groupe est facultatif. Une correspondance se produit s'il existe une troisième séquence de caractères de mot après la deuxième virgule (,) mais aussi s'il n'y en a pas.

Dans ce cas, il n'y en a pas. Il y a donc match global, mais le troisième groupe n'y participe pas. Par conséquent, m.group (3) est toujours défini et est une référence valide, mais il renvoie Aucun:

>>>

>>> impression(m.groupe(3))
Aucun

Il peut également arriver qu'un groupe participe plusieurs fois au match global. Si vous appelez .groupe() pour ce numéro de groupe, il ne renvoie alors que la partie de la chaîne de recherche correspondant à la dernière fois. Les matchs précédents ne sont pas accessibles:

>>>

>>> m = .rencontre(r'( w3,) + ', «foo, bar, baz, qux»)
>>> m
<_sre.SRE_Match object; span=(0, 12), match='foo,bar,baz,'>
>>> m.groupe(1)
«baz»

Dans cet exemple, la correspondance complète est «foo, bar, baz,», comme le montre l'objet de correspondance affiché. Chacun des «foo», 'bar,', et «baz» correspond à ce qui est à l'intérieur du groupe, mais m.group (1) ne renvoie que le dernier match, «baz».

Si vous appelez .groupe() avec un argument de 0 ou aucun argument du tout, il retourne la correspondance entière:

>>>

    1 >>> m = .chercher(r«( w +), ( w +), ( w +)», 'foo, bar, baz')
    2 >>> m
    3 <_sre.SRE_Match object; span=(0, 11), match='foo,bar,baz'>
    4 
    5 >>> m.groupe(0)
    6 'foo, bar, baz'
    7 >>> m.groupe()
    8 'foo, bar, baz'

Ce sont les mêmes données que l'interprète montre après match = quand il affiche l'objet de correspondance, comme vous pouvez le voir sur ligne 3 au dessus de.

match .__ getitem __ ()

Renvoie un groupe capturé d'une correspondance.

match .__ getitem __ () est identique à match.group () et renvoie le seul groupe spécifié par :

>>>

>>> m = .chercher(r«( w +), ( w +), ( w +)», 'foo, bar, baz')
>>> m.groupe(2)
'bar'
>>> m.__obtenir l'article__(2)
'bar'

Si .__obtenir l'article__() reproduit simplement la fonctionnalité de .groupe(), alors pourquoi l'utiliseriez-vous? Vous ne le feriez probablement pas directement, mais vous pourriez le faire indirectement. Lisez la suite pour voir pourquoi.

Une brève introduction aux méthodes magiques

.__obtenir l'article__() fait partie d'une collection de méthodes en Python appelée méthodes magiques. Ce sont des méthodes spéciales que l'interpréteur appelle lorsqu'une instruction Python contient des éléments syntaxiques correspondants spécifiques.

La syntaxe particulière .__obtenir l'article__() correspond à l'indexation entre crochets. Pour tout objet obj, chaque fois que vous utilisez l'expression obj[n], dans les coulisses Python le traduit tranquillement en un appel à .__obtenir l'article__(). Les expressions suivantes sont effectivement équivalentes:

obj[[[[n]
obj.__obtenir l'article__(n)

La syntaxe obj[n] n'a de sens que si un .__obtenir l'article()__ existe pour la classe ou le type auquel obj fait parti. Exactement comment Python interprète obj[n] dépendra alors de la mise en œuvre de .__obtenir l'article__() pour cette classe.

Retour à Match Objects

Depuis Python version 3.6, le le module met en œuvre .__obtenir l'article__() pour faire correspondre les objets. La mise en œuvre est telle que match .__ getitem __ (n) est le même que match.group (n).

Le résultat de tout cela est qu'au lieu d'appeler .groupe() directement, vous pouvez accéder aux groupes capturés à partir d'un objet de correspondance à l'aide de la syntaxe d'indexation entre crochets à la place:

>>>

>>> m = .chercher(r«( w +), ( w +), ( w +)», 'foo, bar, baz')
>>> m.groupe(2)
'bar'
>>> m.__obtenir l'article__(2)
'bar'
>>> m[[[[2]
'bar'

Cela fonctionne également avec les groupes capturés nommés:

>>>

>>> m = .rencontre(
...     r'foo, (? P w +), (? P w +), qux ',
...     «foo, bar, baz, qux»)
>>> m.groupe(«w2»)
«baz»
>>> m[[[[«w2»]
«baz»

C'est quelque chose que vous pourriez réaliser en appelant simplement .groupe() explicitement, mais c'est quand même une jolie notation de raccourci.

Lorsqu'un langage de programmation fournit une syntaxe alternative qui n'est pas strictement nécessaire mais permet l'expression de quelque chose d'une manière plus propre et plus facile à lire, on l'appelle sucre syntaxique. Pour un objet de correspondance, rencontre[n] est du sucre syntaxique pour match.group (n).

match.groups (par défaut = Aucun)

Renvoie tous les groupes capturés d'une correspondance.

match.groups () renvoie un tuple de tous les groupes capturés:

>>>

>>> m = .chercher(r«( w +), ( w +), ( w +)», 'foo, bar, baz')
>>> m.groupes()
('foo', 'bar', 'baz')

Comme vous l'avez vu précédemment, lorsqu'un groupe dans une expression régulière en Python ne participe pas au match global, .groupe() Retour Aucun pour ce groupe. Par défaut, .groupes() fait de même.

Si tu veux .groupes() pour renvoyer autre chose dans cette situation, vous pouvez utiliser le défaut argument de mot clé:

>>>

    1 >>> m = .chercher(r'( w +), ( w +), ( w +)?', 'foo, bar,')
    2 >>> m
    3 <_sre.SRE_Match object; span=(0, 8), match='foo,bar,'>
    4 >>> impression(m.groupe(3))
    5 Aucun
    6 
    7 >>> m.groupes()
    8 ('foo', 'bar', Aucun)
    9 >>> m.groupes(défaut=«---»)
dix ('foo', 'bar', '---')

Ici, le troisième ( w +) le groupe ne participe pas au match car le point d'interrogation (?), le métacaractère le rend facultatif, et la chaîne 'foo, bar,' ne contient pas une troisième séquence de caractères de mot. Par défaut, m.groups () Retour Aucun pour le troisième groupe, comme indiqué sur ligne 8. Sur ligne 10, vous pouvez voir que la spécification par défaut = '---' le fait retourner la chaîne «---» au lieu.

Il n'y a pas de correspondance défaut mot-clé pour .groupe(). Il revient toujours Aucun pour les groupes non participants.

match.groupdict (défaut = Aucun)

Renvoie un dictionnaire des groupes capturés nommés.

match.groupdict () renvoie un dictionnaire de tous les groupes nommés capturés avec le (? P) séquence de métacaractères. Les clés de dictionnaire sont les noms de groupe et les valeurs de dictionnaire sont les valeurs de groupe correspondantes:

>>>

>>> m = .rencontre(
...     r'foo, (? P w +), (? P w +), qux ',
...     «foo, bar, baz, qux»)
>>> m.groupdict()
'w1': 'bar', 'w2': 'baz'
>>> m.groupdict()[[[[«w2»]
«baz»

Comme avec .groupes(), pour .groupdict () le défaut L'argument détermine la valeur de retour pour les groupes non participants:

>>>

>>> m = .rencontre(
...     r'foo, (? P w +), (? P w +) ?, qux ',
...     'foo, bar ,, qux')
>>> m.groupdict()
'w1': 'bar', 'w2': Aucun
>>> m.groupdict(défaut=«---»)
'w1': 'bar', 'w2': '---'

Encore une fois, le dernier groupe (? P w +) ne participe pas au match global en raison du point d'interrogation (?) métacaractère. Par défaut, m.groupdict () Retour Aucun pour ce groupe, mais vous pouvez le changer avec le défaut argument.

match.expand (