Захват нескольких подстрок в одной группе

#python #regex

#python #регулярное выражение

Вопрос:

Теперь у меня есть путь к папке, который будет содержать имя таблицы базы данных и идентификатор, выглядит как:

 path = '/something/else/TableName/000/123/456/789'
  

Конечно, я могу сопоставить TableName/000/123/456/789 , а затем разделить их с помощью скрипта Python.

 import re
matched = re.findall(r'.*?/(w (?:/d ){4})', path)[0]  # TableName/000/123/456/789
split_text = matched.split('/')  # ['TableName', '000', '123', '456', '789']
table_name = split_text[0]  # 'TableName'
id = int(''.join(split_text[1:]))  # 123456789
  

.*?/(w (?:/d ){4})

Но я хочу знать, может ли какая-либо функция, предоставляемая regex, завершить это за один шаг? Я пробовал эти способы:

 re.match(r'.*?/(?P<table_name>w )(?:/(?P<id>d )){4}', path).groupdict()  # {'table_name': 'TableName', 'id': '789'}
re.split(r'.*?/(w )(?:/(d )){4}', path)  # ['', 'TableName', '789', '']
re.sub(r'(.*?/)w (?:(/)d ){4}', '', path)  # '', full string has been replaced
  

.*?/(?Pw )(?:/(?Pd )){4}

.*?/(w )(?:/(d )){4}

Есть ли что-нибудь еще? Или я должен использовать приведенный выше скрипт python? Я надеюсь, что результат будет {'table_name': 'TableName', 'id': '000123456789'} или ('TableName', '000123456789') , по крайней мере ('TableName', '000', '123', '456', '789') .

Комментарии:

1. Я думаю, вам следует использовать pythonic вместо выполнения регулярных выражений

Ответ №1:

Самый простой способ — избежать использования квантора:

 re.findall('(w )/(d )/(d )/(d )/(d )', path)

[('TableName', '000', '123', '456', '789')]
  

Комментарии:

1. Это будет работать на 100%, если порядок в пути исправлен

2. Возможно, вы меня неправильно поняли. Я надеюсь, что результат будет ('TableName', '000123456789') , по крайней мере ('TableName', '000', '123', '456', '789')

3. Самый простой способ — избежать использования кванторов: re.findall(‘(w )/(d )/(d )/(d )/(d )’, path) [(‘имя_таблицы’, ‘000’, ‘123’, ‘456’, ‘789’)]

4. Хорошо, возможно, вы правы. Я только боюсь, что позже будет больше уровней идентификатора. Если нет другого выбора, я думаю, что выберу между вашим ответом и pythonic способом. Большое спасибо!

Ответ №2:

Самым простым способом было бы расширить группировку.

 >>> match=re.search(r'.*?/(w )(?:/(d ))(?:/(d ))(?:/(d ))(?:/(d ))',a)
>>> match.groups()
('TableName', '000', '123', '456', '789')