Python Regex - как получить позиции и значения совпадений

112

Как я могу получить начальную и конечную позиции всех матчей с помощью reмодуля? Например, учитывая шаблон r'[a-z]'и строку, 'a1b2c3d4'я бы хотел получить позиции, в которых она находит каждую букву. В идеале я бы хотел вернуть и текст матча.

Greg
источник
Посмотрите, поможет ли это
сопоставить

Ответы:

140
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())
Питер Хоффманн
источник
3
Это не обеспечивает индекс других групп в совпадении regex = r '([az]) (0-9)' m.start будет для group (), а не group (1)
StevenWernerCS
@StevenWernerCS start()может принимать номер группы, поэтому, если вам нужен индекс n-й группы, используйтеstart(n)
Hi-Angel
@ привет-ангел да, см. мой прошлогодний ответ ниже
StevenWernerCS
51

Взято из

Регулярное выражение HOWTO

span () возвращает как начальный, так и конечный индексы в одном кортеже. Поскольку метод сопоставления проверяет только соответствие RE в начале строки, start () всегда будет нулевым. Однако метод поиска экземпляров RegexObject просматривает строку, поэтому в этом случае совпадение может не начинаться с нуля.

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

Совместите это с:

В Python 2.2 также доступен метод finditer (), возвращающий последовательность экземпляров MatchObject в качестве итератора.

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

вы должны уметь делать что-то в порядке

for match in re.finditer(r'[a-z]', 'a1b2c3d4'):
   print match.span()
ушел
источник
Вы можете использовать это как re.search(r'abbit', "has abbit of carrot").span(0)-(4, 9)
Константин Ван
«Конечный индекс», возвращаемый функцией, span()похож на «стоп» в нотации фрагментов Python в том смысле, что он идет вверх, но не включает этот индекс; см. здесь .
Уэйн
20

Для Python 3.x

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

Вы должны получить \nотдельные кортежи (включающие первый и последний индексы совпадения соответственно) и само совпадение для каждого совпадения в строке.

Бараны здесь
источник
2

обратите внимание, что диапазон и группа индексируются для групп с несколькими захватами в регулярном выражении

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))
Стивен Вернер CS
источник
1
Спасибо, это оказалось очень полезным и, кажется, похоронено. Кроме того, на случай, если кому-то это понадобится: при использовании именованных групп захвата можно найти индекс группы с помощью <match> .re.groupindex, а оттуда найти соответствующий диапазон, используя описанный вами подход
madimov
откуда 4взялось?
Radio Controlled
@RadioControlled number_of_known_groups_in_the_regex + 1, поскольку диапазон равен [начало, конец),
исключая
@StevenWernerCS, поэтому он не распространяется на случаи, когда количество групп неизвестно ...
Radio Controlled