replace и перекрывающиеся подстроки в Python
@python_quizРазберем этот квиз
Коротко: метод str.replace не находит перекрывающиеся вхождения. Его поиск идёт слева направо и после замены позиция сдвигается за заменённую подстроку.
Условие (код)

Что выведет программа
Этот код выведет:

Объяснение: в строке 'ababa' подстрока 'aba' встречается на позициях 0–2 и 2–4 (они перекрываются). str.replace находит первое вхождение (0–2), заменяет его на 'X' и продолжае поиск после заменённого фрагмента (т.е. начинает с позиции 3). Оставшаяся часть строки — 'ba' — содержит уже слишком мало символов для новой подстроки 'aba', поэтому дальнейших замен не происходит. Ограничение count=1 явно задаёт максимум замен, но в данном случае и без него заменилось бы только одно вхождение, потому что второе перекрывающееся вхождение просто не считается.
Разбор вариантов вывода (интерпретация)
- "Xba и Xba" — совпадает с тем, что действительно печатается.
- "Xba и XbaX" — предполагает, что вторая команда сделала две замены или позволила бы добавочной замене в конце; это неверно из‑за отсутствия неперекрывающегося второго вхождения.
- "Xba и XbaXba" — неправдоподобно: ни одна из строк не даёт такого результата.
- "Xba и Xba" — дублирует первый вариант и тоже совпадает с выводом.
(Ключевой момент: replace не учитывает перекрывающиеся вхождения при последовательном поиске.)
Как найти перекрывающиеся вхождения, если нужно
Если вы хотите обнаружить все начала перекрывающихся совпадений (без внесения замен), можно использовать регулярные выражения с lookahead:

Если же требуется заменить все перекрывающиеся вхождения по вашему собственному правилу, придётся реализовать логику вручную (или использовать подходящий алгоритм). Пример простого подхода, который допускает "перескок" на 1 символ после нахождения совпадения (т.е. позволяет учитывать перекрытия при замене — результат зависит от выбранной семантики):

Обратите внимание: реализация семантики замены с перекрытиями зависит от того, что вы подразумеваете под «заменой»: если каждая найденная подстрока должна быть удалена/заменена и при этом не должна влиять на обнаружение других — нужны дополнительные правила, и результаты могут быть неочевидны.
Вывод
- str.replace работает только с неперекрывающимися вхождениями, и поиск идёт слева направо.
- Для поиска перекрывающихся вхождений используйте регулярные выражения с lookahead.
- Для «замены с учётом перекрытий» требуются явные алгоритмы — поведение зависит от выбранной интерпретации перекрытий.