Python Regex - Comment obtenir des positions et des valeurs de correspondances

112

Comment puis-je obtenir les positions de début et de fin de tous les matchs à l'aide du remodule? Par exemple, étant donné le modèle r'[a-z]'et la chaîne, 'a1b2c3d4'je voudrais obtenir les positions où il trouve chaque lettre. Idéalement, j'aimerais aussi récupérer le texte du match.

Greg
la source
Voyez si cela aide à faire correspondre les objets
EBGreen

Réponses:

140
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())
Peter Hoffmann
la source
3
Cela ne fournit pas d'index des autres groupes dans un match regex = r '([az]) (0-9)' m.start sera pour le groupe (), pas pour le groupe (1)
StevenWernerCS
@StevenWernerCS start()peut accepter un numéro de groupe, donc si vous voulez un index du nième groupe, utilisezstart(n)
Hi-Angel
@ hi-angel yep, voir ma réponse ci-dessous de l'année dernière qui fait exactement cela
StevenWernerCS
51

Pris à partir de

HOWTO sur les expressions régulières

span () retourne les index de début et de fin dans un seul tuple. Puisque la méthode match vérifie uniquement si le RE correspond au début d'une chaîne, start () sera toujours égal à zéro. Toutefois, la méthode de recherche des instances de RegexObject analyse la chaîne, de sorte que la correspondance peut ne pas commencer à zéro dans ce cas.

>>> p = re.compile('[a-z]+')
>>> print p.match('::: message')
None
>>> m = p.search('::: message') ; print m
<re.MatchObject instance at 80c9650>
>>> m.group()
'message'
>>> m.span()
(4, 11)

Combinez cela avec:

Dans Python 2.2, la méthode finditer () est également disponible, renvoyant une séquence d'instances MatchObject en tant qu'itérateur.

>>> p = re.compile( ... )
>>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...')
>>> iterator
<callable-iterator object at 0x401833ac>
>>> for match in iterator:
...     print match.span()
...
(0, 2)
(22, 24)
(29, 31)

vous devriez pouvoir faire quelque chose de l’ordre de

for match in re.finditer(r'[a-z]', 'a1b2c3d4'):
   print match.span()
disparu
la source
Vous pouvez l'utiliser comme re.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
Константин Ван
L '«index de fin» retourné par le span()est comme le «stop» dans la notation de tranche de Python en ce sens qu'il va jusqu'à mais n'inclut pas cet index; voir ici .
Wayne
20

Pour Python 3.x

from re import finditer
for match in finditer("pattern", "string"):
    print(match.span(), match.group())

Vous obtiendrai \ntuples (séparés comprenant des premier et derniers indices du match, respectivement) et le match lui - même, pour chaque coup dans la chaîne.

Béliers ici
la source
2

notez que la plage et le groupe sont indexés pour plusieurs groupes de capture dans une expression régulière

regex_with_3_groups=r"([a-z])([0-9]+)([A-Z])"
for match in re.finditer(regex_with_3_groups, string):
    for idx in range(0, 4):
        print(match.span(idx), match.group(idx))
StevenWernerCS
la source
1
Merci, cela s'est avéré super utile et semble être assez enterré. De plus, au cas où quelqu'un en aurait besoin: lors de l'utilisation de groupes de capture nommés, on peut trouver l'index d'un groupe en utilisant <match> .re.groupindex, et à partir de là, trouver le span correspondant en utilisant l'approche que vous avez décrite
madimov
d'où vient le 4?
Radiocommandé le
@RadioControlled number_of_known_groups_in_the_regex + 1, car la plage est [start, end) exclusive of end
StevenWernerCS
@StevenWernerCS donc il ne se généralise pas aux cas où le nombre de groupes n'est pas connu ...
Radiocommandé