Python Regex - Як отримати позиції та значення збігів


112

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


Подивіться, чи це допомагає об'єктам матчу
EBGreen

Відповіді:


140
import re
p = re.compile("[a-z]")
for m in p.finditer('a1b2c3d4'):
    print(m.start(), m.group())

3
Це не дає індексу інших груп у регекс матчу = r '([az]) (0-9)' m.start буде для групи (), а не для групи (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))

1
Дякую, це виявилося надзвичайно корисним і, здається, досить поховано. Також, якщо комусь це потрібно: використовуючи названі групи захоплення, можна знайти індекс групи за допомогою <match> .re.groupindex, а звідти знайти відповідний проміжок, використовуючи окреслений вами підхід
madimov

звідки 4походить?
Радіокерований

@RadioContROL number_of_known_groups_in_the_regex + 1, оскільки діапазон [початок, кінець) не
враховує

@StevenWernerCS, щоб не узагальнити випадки, коли кількість груп не відома ...
Радіоконтрольовано
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.