Повторение регулярных выражений Python с вопросом захвата - PullRequest
2 голосов
/ 13 июля 2011

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

поиск строки 1 (пытается захватить: 89, 45):

zzz89zzz45.mp3

строка поиска 2 (пытается захватить: 98, 67, 89, 45):

zzz98zzz67zzz89zzz45.mp3

строка поиска 3 (пытается захватить: 98, 67, 89, 45, 55, 111):

zzz98zzz67zzz89zzz45vdvd55lplp111.mp3

следующее регулярное выражение будет соответствовать всем повторениям, хотя все значения недоступны для последующего использования (фиксируется только 1-разрядная строка):

((\d+)\D*)*\.mp3$

другие 2 опции пишут разные регулярные выражения для каждого случая или используют findall (). Есть ли способ настроить вышеупомянутое регулярное выражение, чтобы захватить каждую цифровую строку для последующего использования с различным числом повторений, используя только средства регулярного выражения, или для того, чтобы сделать это в python3, вы вынуждены использовать findall ()?

Ответы [ 2 ]

3 голосов
/ 13 июля 2011

Большинство или все обычные механизмы регулярных выражений, включая, в частности, те, которые основаны на синтаксисе PCRE (например, Python), маркируют свои группы захвата в соответствии с числовым индексом открывающей скобки, при написании регулярного выражения .Поэтому нет, вы не можете использовать группы захвата в одиночку для извлечения произвольного, переменного числа подпоследовательностей из строки.

Самое близкое, что вы можете получить (насколько я знаю), - выписать определенное количество записей вручную.группы, что-то вроде этого:

s = ...
res = re.match(r'\D*' + 25 * r'(\d+)\D+')
numbers = [r for r in res.groups() if r is not None]

Это даст вам до 25 групп цифр.Если вам нужно больше, замените 25 на более высокое число.

Я бы не удивился, если бы это было менее эффективно, чем итеративный подход с findall(), хотя я не проверял его.

3 голосов
/ 13 июля 2011

Это будет соответствовать всем числам перед точкой:

s = "zzz98zzz67zzz89zzz45vdvd55lplp111.mp3"
res = re.findall("[0-9]+(?=.*\\.)", s)
print(res)
...