Как найти совпадающие совпадения с регулярным выражением?
>>> match = re.findall(r'\w\w', 'hello')
>>> print match
['he', 'll']
Поскольку \w\w означает два символа, ожидается, что он и я. Но почему 'el' и 'lo' не соответствуют регулярному выражению?
>>> match1 = re.findall(r'el', 'hello')
>>> print match1
['el']
>>>
3 ответа
findall
по умолчанию не дает перекрывающихся совпадений. Это выражение делает однако:
>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']
Вот (?=...)
это предвидение утверждения:
(?=...)
соответствует, если...
соответствует следующему, но не использует ни одной строки. Это называется косвенным утверждением. Например,Isaac (?=Asimov)
будет соответствовать'Isaac '
только если это сопровождается'Asimov'
,
Вы можете использовать новый модуль регулярных выражений Python, который поддерживает перекрывающиеся совпадения.
>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']
За исключением утверждения нулевой длины, символ на входе всегда будет использоваться при сопоставлении. Если вы когда-нибудь захотите захватить определенный символ во входной строке более одного раза, вам понадобится утверждение нулевой длины в регулярном выражении.
Есть несколько утверждений нулевой длины (например, ^
(начало ввода / строки), $
(конец ввода / строки), \b
(граница слова)), но осмотры ((?<=)
позитивный взгляд и (?=)
положительный прогноз) - это единственный способ получить перекрывающийся текст из входных данных. Негативные осмотры ((?<!)
негативный взгляд, (?!)
негативный прогноз) здесь не очень полезны: если они утверждают истину, то захват внутри не удался; если они утверждают ложь, то совпадение не удается. Эти утверждения имеют нулевую длину (как упоминалось ранее), что означает, что они будут утверждаться без использования символов во входной строке. Они фактически будут соответствовать пустой строке, если утверждение пройдет.
Используя приведенные выше знания, регулярное выражение, которое подходит для вашего случая:
(?=(\w\w))
Я не эксперт по регулярным выражениям, но я хотел бы ответить на мой похожий вопрос.
Если вы хотите использовать группу захвата с предвидением:
пример регулярного выражения: (\d)(?=.\1)
строка: 5252
это будет соответствовать первым 5, а также первым 2
(\ D) - создать группу захвата, (?=\ D \ 1) - сопоставить любую цифру, за которой следует группа 1 захвата, без использования строки, что позволяет перекрывать друг друга