Как найти совпадающие совпадения с регулярным выражением?

>>> match = re.findall(r'\w\w', 'hello')
>>> print match
['he', 'll']

Поскольку \ w \ w означает два символа, ожидаются символы he и ll. Но почему "el" и "lo" не соответствуют регулярному выражению?

>>> match1 = re.findall(r'el', 'hello')
>>> print match1
['el']
>>>

person futurenext110    schedule 11.07.2012    source источник
comment
Lookahead   -  person Pavan Manjunath    schedule 11.07.2012


Ответы (4)


findall по умолчанию не дает совпадающих совпадений. Однако это выражение:

>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']

Здесь (?=...) - это утверждение просмотра вперед:

(?=...) соответствует, если ... соответствует следующему, но не использует ни одной строки. Это называется предварительным утверждением. Например, Isaac (?=Asimov) будет соответствовать 'Isaac ', только если за ним следует 'Asimov'.

person Otto Allmendinger    schedule 11.07.2012
comment
Но я не понимаю, почему он переходит к следующей букве, если он находится внутри утверждения положительного просмотра вперед. Не могли бы вы объяснить? - person MrZH6; 02.04.2020

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

>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']
person David C    schedule 23.09.2013

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

Есть несколько утверждений нулевой длины (например, ^ (начало ввода / строки), $ (конец ввода / строки), \b (граница слова)), но взгляд вокруг ((?<=) положительный взгляд назад и (?=) положительный взгляд вперед ) - единственный способ захватить перекрывающийся текст из ввода. Отрицательные осмотры ((?<!) отрицательный взгляд назад, (?!) отрицательный взгляд вперед) здесь не очень полезны: если они подтверждают истину, то захват внутри не удался; если они утверждают ложь, то совпадение не выполняется. Эти утверждения имеют нулевую длину (как упоминалось ранее), что означает, что они будут утверждаться без использования символов во входной строке. Они фактически будут соответствовать пустой строке, если утверждение пройдет.

Применяя вышеизложенные знания, регулярное выражение, которое работает в вашем случае, будет:

(?=(\w\w))
person nhahtdh    schedule 11.07.2012

Я не эксперт по регулярным выражениям, но хотел бы ответить на свой аналогичный вопрос.

Если вы хотите использовать группу захвата с опережением:

пример регулярного выражения: (\d)(?=.\1)

строка: 5252

это будет соответствовать первым 5, а также первым 2

(\d) - это создать группу захвата, (?=\d\1) - соответствовать любой цифре, за которой следует группа захвата 1, без использования строки, таким образом разрешая перекрытие

person Obay Abd-Algader    schedule 04.02.2019