Як знайти збіги, що перекриваються, із регулярним виразом?


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

Оскільки \ w \ w означає два символи, очікується "він" і "ll". Але чому 'el' і 'lo' не відповідають регулярному виразу?

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

Відповіді:


110

findallза замовчуванням не дає збігів, що перекриваються. Однак цей вираз означає:

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

Ось (?=...)це випередження затвердження :

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


Але я не розумію, чому він переходить до наступного листа, якщо він знаходиться всередині позитивного твердження про перегляд. Не могли б ви пояснити, будь ласка?
MrZH6


11

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

Є кілька тверджень нульової довжини (наприклад, ^(початок вводу / рядка), $(кінець вводу / рядка), \b(межа меж)), але оглядові сторони ( (?<=)позитивний огляд і (?=)позитивний огляд вперед) - єдиний спосіб що ви можете захопити текст, що накладається, із вводу. Негативні огляди ( (?<!)негативний огляд, (?!)негативний огляд уперед) тут не дуже корисні: якщо вони стверджують, що це істина, то захоплення всередині не вдалося; якщо вони стверджують, що помилкові, то збіг не вдається. Ці твердження мають нульову довжину (як уже згадувалося раніше), що означає, що вони будуть стверджуватись, не споживаючи символів у вхідному рядку. Вони фактично збігатимуться з порожнім рядком, якщо твердження пройде.

Застосовуючи наведені вище знання, регулярним виразом, який підходить для Вашого випадку, буде:

(?=(\w\w))

0

Я не фахівець з регулярних виразів, але я хотів би відповісти на моє подібне запитання .

Якщо ви хочете скористатися групою захоплення за допомогою пошуку:

приклад регулярного виразу: (\ d) (? =. \ 1)

рядок: 5252

це буде відповідати першим 5, а також першим 2

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.