Группы захвата регулярных выражений в Python с примерами

Предположим, у вас есть следующий путь, по которому на веб-сайте отображаются новости с идентификатором 100:

news/100

Следующее регулярное выражение соответствует указанному выше пути:

\w+/\d+

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

В этом шаблоне:

  • \w+ — это набор символов слова с квантификатором(+), который соответствует одному или нескольким символам слова.
  • / сравнивает косую черту / символ.
  • \d+ — это набор символов цифр с квантификатором(+), который соответствует одной или нескольким цифрам.

Следующая программа использует шаблон \w+/\d+ для соответствия строке «news/100»:

import re

s = 'news/100'
pattern = '\w+/\d+'

matches = re.finditer(pattern,s)
for match in matches:
    print(match)

Выход:

<re.Match object; span=(0, 8), match='news/100'>

Он показывает одно совпадение, как и ожидалось.

Содержание

Создание группы захвата регулярных выражений в Python

Чтобы получить идентификатор из пути, вы используете группу захвата. Чтобы определить группу захвата для шаблона, вы помещаете правило в круглые скобки:

(rule)

Например, чтобы создать группу захвата регулярных выражений в Python, которая захватывает идентификатор из пути, вы используете следующий шаблон:

'\w+/(\d+)'

В этом шаблоне мы помещаем правило \d+ внутри круглых скобок(). Если вы запустите программу с новым шаблоном, вы увидите, что она отображает одно совпадение:

import re

s = 'news/100'
pattern = '\w+/(\d+)'

matches = re.finditer(pattern, s)
for match in matches:
    print(match)

Выход:

<re.Match object; span=(0, 8), match='news/100'>

Чтобы получить группы захвата из совпадения, вы используете метод group() объекта Match:

match.group(index)

Группа(0) вернет все совпадение, а группа(1), группа(2) и т. д. вернет первую, вторую и… группу.

Свойство Lastindex объекта Match возвращает последний индекс всех подгрупп. Следующая программа показывает все совпадение (группу(0)) и все подгруппы:

import re

s = 'news/100'
pattern = '\w+/(\d+)'

matches = re.finditer(pattern, s)
for match in matches:
    for index in range(0, match.lastindex + 1):
        print(match.group(index))

Выход:

news/100
100

В выводе news/100 — это все совпадение, а 100 — это подгруппа.

Если вы хотите также захватить ресурс (новости) по пути(news/100), вы можете создать дополнительную группу захвата следующим образом:

'(\w+)/(\d+)'

В этом шаблоне у нас есть две группы захвата: одна для \w+, а другая для \d+. Следующая программа показывает match.group и все подгруппы:

import re

s = 'news/100'
pattern = '(\w+)/(\d+)'

matches = re.finditer(pattern, s)
for match in matches:
    for index in range(0, match.lastindex + 1):
        print(match.group(index))

Выход:

news/100
news
100

В выводе news/100 — это все совпадение, а news и 100 — это подгруппы.

Именованные группы захвата

По умолчанию вы можете получить доступ к подгруппе в совпадении, используя индекс, например match.group(1). Иногда доступ к подгруппе по значимому имени оказывается более удобным.

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

(?P<name>rule)

В этом синтаксисе:

  • () указывает на группу захвата.
  • ?P указывает имя группы захвата.
  • правило — это правило в шаблоне.

Например, следующее создает имена:

'(?P<resource>\w+)/(?P<id>\d+)'

В этом синтаксисе ресурс — это имя первой группы захвата, а идентификатор — имя второй группы захвата.

Чтобы получить все именованные подгруппы совпадения, вы используете метод groupdict() объекта Match. Например:

import re

s = 'news/100'
pattern = '(?P<resource>\w+)/(?P<id>\d+)'

matches = re.finditer(pattern, s)
for match in matches:
    print(match.groupdict())

Выход:

{'resource': 'news', 'id': '100'}

В этом примере метод groupdict() возвращает словарь, где ключами являются имена групп, а значениями — подгруппы.

Пример группы захвата с другим названием

Следующий шаблон:

\w+/d{4}/d{2}/d{2}

соответствует этому пути:

news/2021/12/31

И вы можете добавить именованные группы захвата в шаблон следующим образом:

'(?P<resource>\w+)/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})'

Эта программа использует шаблоны для сопоставления пути и показывает все подгруппы:

import re

s = 'news/2021/12/31'
pattern = '(?P<resource>\w+)/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})'

matches = re.finditer(pattern, s)
for match in matches:
    print(match.groupdict())

Выход:

{'resource': 'news', 'year': '2021', 'month': '12', 'day': '31'}
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *