Python: уроки, справочник и задачи

Python string replace: как заменить подстроку

Раздел: Строки в Python · Обновлено 31.10.2026

Метод replace() в Python заменяет в строке все вхождения одной подстроки на другую и возвращает новую строку. Из статьи вы узнаете синтаксис и параметр count, способы удалить символы, сделать несколько замен за раз, заменить только последнее вхождение и когда вместо replace() лучше взять translate() или регулярные выражения.

Python string replace
Фото: DS Pugh / CC BY-SA 2.0, Wikimedia Commons
Содержание статьи
  1. Синтаксис и параметры
  2. Строка не меняется на месте
  3. Ограничение числа замен
    1. Замена последнего вхождения
  4. Удаление символов из строки
  5. Несколько замен за один раз
    1. Цепочка вызовов и словарь
    2. translate() для отдельных символов
    3. re.sub() для шаблонов
  6. Что выбрать для замены
  7. Частые вопросы
    1. Почему replace() не изменил строку?
    2. Можно ли заменить без учета регистра?
    3. Как заменить символ по индексу?
    4. Как применить replace() ко всем строкам списка?
    5. Что будет, если old - пустая строка?

Синтаксис и параметры

Метод вызывается у строки и принимает два обязательных аргумента и один необязательный:

str.replace(old, new, count=-1)

Начиная с Python 3.13 count можно передавать по имени: s.replace('a', 'b', count=1). В более ранних версиях он принимается только позиционно, а вызов с именем дает TypeError.

text = 'bat ball'
print(text.replace('b', 'c'))       # cat call
print(text.replace('ball', 'cap'))  # bat cap

Поиск идет слева направо, а найденные фрагменты не перекрываются. Например, 'aaaa'.replace('aa', 'b') вернет 'bb', а не три замены.

Строка не меняется на месте

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

city = 'Санкт Петербург'
city.replace(' ', '-')      # результат потерян
print(city)                 # Санкт Петербург

city = city.replace(' ', '-')
print(city)                 # Санкт-Петербург

Если подстрока не найдена, метод вернет строку с тем же содержимым, ошибки не будет. Поэтому заранее проверять вхождение через in перед заменой не нужно. О способах поиска подстроки рассказано в отдельной статье про поиск подстроки.

Ограничение числа замен

Параметр count позволяет заменить только первые N совпадений. Это удобно, когда нужно поменять первое вхождение, а остальные оставить.

log = 'ERROR: disk ERROR: net ERROR: cpu'
print(log.replace('ERROR', 'WARN', 1))
# WARN: disk ERROR: net ERROR: cpu
print(log.replace('ERROR', 'WARN', 2))
# WARN: disk WARN: net ERROR: cpu
print(log.replace('ERROR', 'WARN', 0))
# ERROR: disk ERROR: net ERROR: cpu

При count=0 замен нет совсем. Отрицательное значение означает "заменить все".

Замена последнего вхождения

Отдельного параметра для замены с конца у replace() нет. Задачу решает сочетание rsplit() и join(): строка разрезается по последнему вхождению и склеивается обратно с новой подстрокой.

path = 'docs/report.old.old'
result = '.new'.join(path.rsplit('.old', 1))
print(result)  # docs/report.old.new

Удаление символов из строки

Если передать пустую строку в качестве new, найденные фрагменты просто исчезнут. Так удаляют пробелы, переносы строк, знаки валют и другой мусор.

price = '1 299 руб.'
print(price.replace(' ', '').replace('руб.', ''))  # 1299

line = 'строка\r\n'
print(repr(line.replace('\r', '')))               # 'строка\n'

Чтобы убрать пробелы только по краям строки, а не внутри, используйте strip(). replace(' ', '') удалит все пробелы, включая пробелы между словами.

Несколько замен за один раз

replace() принимает только одну пару "что на что". Для нескольких замен есть три подхода.

Цепочка вызовов и словарь

Каждый вызов возвращает строку, поэтому методы можно вызывать подряд. При большом числе пар их удобнее хранить в словаре и обходить циклом.

phone = '+7 (999) 123-45-67'
digits = phone.replace(' ', '').replace('(', '').replace(')', '').replace('-', '')
print(digits)  # +79991234567

abbr = {'т.е.': 'то есть', 'т.к.': 'так как'}
text = 'Не работает, т.к. нет сети, т.е. офлайн'
for old, new in abbr.items():
    text = text.replace(old, new)
print(text)  # Не работает, так как нет сети, то есть офлайн

У цикла есть ловушка: замены выполняются по очереди, и результат одной может попасть под следующую. Например, при парах a на b и b на c буква a в итоге станет c.

translate() для отдельных символов

Когда нужно заменить или удалить много одиночных символов, быстрее и надежнее метод translate() с таблицей из str.maketrans(). Все замены делаются за один проход, поэтому описанной выше ловушки нет.

table = str.maketrans({'ё': 'е', 'Ё': 'Е', ';': ','})
print('Ёлка; ёж'.translate(table))  # Елка, еж

no_digits = str.maketrans('', '', '0123456789')
print('a1b2c3'.translate(no_digits))   # abc

re.sub() для шаблонов

Регулярные выражения нужны, если подстрока не фиксирована: любые цифры, несколько пробелов подряд, слово в любом регистре. Функция re.sub() из модуля re заменяет все совпадения с шаблоном.

import re

print(re.sub(r'\s+', ' ', 'много    пробелов   тут'))  # много пробелов тут
print(re.sub('python', 'Python', 'PYTHON и python', flags=re.I))
# Python и Python
print(re.sub(r'\d', '*', 'Карта 4276 1234'))           # Карта **** ****

Что выбрать для замены

Сравнение способов поможет быстро подобрать инструмент под задачу.

ЗадачаСпособОсобенность
Заменить фиксированную подстрокуreplace()Самый простой и быстрый вариант
Заменить первые N вхожденийreplace(old, new, n)Отсчет идет слева
Заменить последнее вхождениеrsplit() и join()Отдельного метода нет
Много одиночных символовtranslate()Один проход, замены не мешают друг другу
Шаблон или любой регистрre.sub()Гибко, но медленнее replace()

Другие операции со строками собраны в справочнике по методам строк.

Частые вопросы

Ответы на вопросы, которые чаще всего задают о замене текста в Python.

Почему replace() не изменил строку?

Метод возвращает новую строку и не трогает исходную. Присвойте результат: s = s.replace('a', 'b').

Можно ли заменить без учета регистра?

replace() различает регистр: 'Python' и 'python' для него разные строки. Для замены без учета регистра используйте re.sub() с флагом re.IGNORECASE.

Как заменить символ по индексу?

Строку нельзя изменить по индексу, присваивание s[0] = 'X' вызовет TypeError. Соберите новую строку срезами: s = s[:i] + 'X' + s[i + 1:].

Как применить replace() ко всем строкам списка?

Используйте генератор списка: [item.replace(',', '.') for item in values]. У самого списка метода replace() нет.

Что будет, если old - пустая строка?

Новая подстрока вставится между всеми символами, а также в начало и конец: 'abc'.replace('', '-') вернет '-a-b-c-'.