Python Regex - Como obter posições e valores de correspondências

112

Como posso obter as posições inicial e final de todas as partidas usando o remódulo? Por exemplo, dado o padrão r'[a-z]'e a string 'a1b2c3d4', gostaria de obter as posições em que cada letra encontra. Idealmente, gostaria de obter o texto do jogo de volta também.

Greg
fonte
Veja se isso ajuda a combinar objetos
EBGreen

Respostas:

140
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())
Peter Hoffmann
fonte
3
Isso não fornece o índice de outros grupos em uma correspondência regex = r '([az]) (0-9)' m.start será para o grupo (), não o grupo (1)
StevenWernerCS
@StevenWernerCS start()pode aceitar um número de grupo, então se você quiser um índice do enésimo grupo, usestart(n)
Hi-Angel
@ oi-angel sim, veja minha resposta abaixo do ano passado que faz exatamente isso
StevenWernerCS
51

Tirado de

Regular Expression HOWTO

span () retorna os índices inicial e final em uma única tupla. Uma vez que o método de correspondência só verifica se a RE corresponde no início de uma string, start () será sempre zero. No entanto, o método de pesquisa de ocorrências de RegexObject examina a string, de modo que a correspondência não pode começar do zero nesse caso.

>>> 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)

Combine isso com:

No Python 2.2, o método finditer () também está disponível, retornando uma sequência de instâncias MatchObject como um iterador.

>>> 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)

você deve ser capaz de fazer algo na ordem de

for match in re.finditer(r'[a-z]', 'a1b2c3d4'):
   print match.span()
foi
fonte
Você pode usá-lo como re.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
Константин Ван
O 'índice final' retornado pelo span()é como a 'parada' na notação de fatia do Python, pois vai até, mas não inclui esse índice; veja aqui .
Wayne de
20

Para Python 3.x

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

Você deve obter \ntuplas separadas (compreendendo o primeiro e o último índices da correspondência, respectivamente) e a própria correspondência, para cada acerto na string.

Rams Here
fonte
2

observe que o span e o grupo são indexados para grupos de captura múltipla em um regex

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
fonte
1
Obrigado, isso se provou super útil e parece estar bastante enterrado. Além disso, caso alguém precise disso: ao usar grupos de captura nomeados, pode-se encontrar o índice de um grupo usando <match> .re.groupindex e, a partir daí, encontrar o intervalo correspondente usando a abordagem que você descreveu
madimov
de onde 4vem?
Rádio controlado em
@RadioControlled number_of_known_groups_in_the_regex + 1, pois o intervalo é [início, fim) exclusivo do fim
StevenWernerCS
@StevenWernerCS portanto não generaliza para casos onde o número de grupos não é conhecido ...
Rádio Controlado em