replace: замена подстрок
Заменить одно слово на другое во всём тексте, убрать мусор из середины строки, вычистить телефон до одних цифр — всё это делает один метод: replace.
Редакция Питоники
strip чистит края строки, но мусор часто сидит в середине: старое название товара внутри описания, лишние пробелы между словами, дефисы в номере телефона. Метод replace заменяет подстроку где угодно — и делает это со всеми вхождениями сразу.
Сценарий: телефон приходит с мусором
Пользователь вводит телефон как удобно: «+7 (912) 000-00-00», «8 800 555-35-35», «тел.: 8-800-555-35-35». Для человека это один и тот же номер, для программы — три разные строки. Сравнивать их напрямую бессмысленно: сначала нужно привести к общему виду, и вот тут replace незаменим.
phones = ['+7 (912) 000-00-00', '8 (800) 555-35-35']
for p in phones:
digits = p.replace(' ', '').replace('(', '').replace(')', '').replace('-', '')
print(digits)
+79120000000 88005553535
Четыре замены подряд убрали пробелы, скобки и дефисы, и остались одни цифры с плюсом. Порядок здесь не важен — все четыре замены независимы, — но длина цепочки всегда равна числу разных видов мусора. Если в данных вдруг появится точка или двоеточие, цепочку придётся дополнить, и забыть об этом легко: программа не ругается, а просто пропускает символ.
replace: все вхождения сразу
phrase = 'кот, код, кот'
print(phrase.replace('кот', 'пёс'))
пёс, код, пёс
Схема: s.replace(старая, новая) — найди каждую подстроку «старая» и поставь на её место «новая». Обратите внимание: заменились оба вхождения, а не только первое — replace по умолчанию обрабатывает строку целиком. Слово «код» не пострадало: replace ищет подстроку целиком, и «код» на «кот» не похож.
text = 'кот'
print(text.replace('пёс', 'кот'))
кот
Если старой подстроки в строке нет, replace не ругается: он вернёт исходную строку без изменений. Это удобное свойство для чистки данных — вызов можно ставить без всяких проверок «а есть ли там что-то».
Третий аргумент: сколько замен сделать
text = 'а-а-а-а'
print(text.replace('-', '.', 2))
print(text.replace('-', '.'))
а.а.а-а а.а.а.а
Необязательный третий аргумент считает замены слева направо и останавливается, когда лимит исчерпан: replace('-', '.', 2) заменил первые два дефиса, третий устоял. Без лимита заменились все. Это же число работает и в обратную сторону: заменить нужно не всё, а только первое вхождение — ставьте лимит 1.
Замена на пустую строку — удаление
messy = 'к о т к о д'
print(messy.replace(' ', ''))
коткод
Грабли: порядок замен и регистр
Две ошибки в цепочках replace встречаются чаще всего. Первая — порядок замен: если новая подстрока содержит старую, вторая замена может испортить результат. Вторая — регистр: replace ищет подстроку буквально, поэтому «Кот» и «кот» для него разные вещи.
s = 'аб'
print(s.replace('а', 'б').replace('б', 'а'))
print(s.replace('б', 'а').replace('а', 'б'))
аа бб
Обе цепочки меняют местами две буквы, но дают разный результат. В первой первая замена превратила «а» в «б», и вторая переписала уже обе буквы обратно в «а» — получилась «аа». Во второй всё наоборот: «б» стала «а», а потом обе «а» превратились в «б». Правило простое: если новая подстрока содержит старую, сначала избавляются от старой, и только потом делают замену — или подставляют временную метку.
text = 'Кот и кот и КОТ'
print(text.replace('кот', 'пёс'))
Кот и пёс и КОТ
price = '1250.50 руб.'
print(repr(price.replace('руб', '')))
print(repr(price.replace('р', '')))
'1250.50 .' '1250.50 уб.'
Цепочки вызовов
replace возвращает новую строку — значит, у неё сразу можно вызвать следующий replace. Так собирают конвейер чистки: каждый шаг вырезает свой мусор.
raw = ' Цена: 1 000 руб. '
clean = raw.strip().replace(' руб.', '').replace('Цена:', '').replace(' ', '')
print(clean)
1000
Цепочка сработала слева направо: strip снял края — остатки разбирали три replace подряд. Результат записан в переменную — без присваивания вся работа пропала бы даром: строки неизменяемы, и методы регистра живут по тому же правилу. Финальный пример — исправить опечатку во всём отчёте одной строкой на элемент:
report = ['ошибка в строке 1', 'ошибка в строке 2']
for line in report:
print(line.replace('ошибка', 'правка'))
правка в строке 1 правка в строке 2
s = 'а-б-в-г'
print(s.replace('-', '+', 1))
print(s[:s.rfind('-')] + '+' + s[s.rfind('-') + 1:])
а+б-в-г а-б-в+г
Когда replace уже не справляется
Replace умеет искать только точную подстроку. Как только в данных появляются варианты — «кот», «Кот», «кОт», «котик» — цепочка замен разрастается и всё равно находит не всё. Тогда задача меняется: нужен уже не текстовый поиск, а разбор по шаблону.
Практическое правило: если список замен перевалил за две-три штуки, стоит остановиться и подумать, не проще ли разобрать строку на части и собрать заново. Часто дешевле split плюс обработка каждой части, чем десяток replace подряд.
Чем что чинить
| Задача | Инструмент | Пример |
|---|---|---|
| Убрать пробелы по краям | strip | ' кот ' → 'кот' |
| Убрать мусор из середины | replace | s.replace('-', '') |
| Заменить подстроку на другую | replace | s.replace('кот', 'пёс') |
| Разобрать на части по разделителю | split | row.split(',') |
| Собрать из частей обратно | join | ', '.join(parts) |
| Взять кусок по границам | срез | s[4:8] |
Replace занимает в этой таблице две строки, и это честно: он единственный из строковых методов, который умеет менять содержимое, не трогая длину строки и не разбирая её на части. Остальные либо чистят края, либо режут.
Замена внутри списков и словарей
Данные редко лежат в одной строке — чаще это список товаров или словарь цен, и замену нужно применить к каждому элементу. Тут же включается приём, который мы разбирали в уроке про строки и списки: список собирается заново, потому что менять существующий нельзя.
words = ['кот-1', 'код-2']
fixed = [w.replace('-', '_') for w in words]
print(fixed)
prices = {'кот-1': 100}
clean = {k.replace('-', '_'): v for k, v in prices.items()}
print(clean)
['кот_1', 'код_2']
{'кот_1': 100}Списком и словарём — два разных случая, а идея одна: взять старое значение, применить к нему replace и положить результат в новое место. Ключи словаря при этом тоже можно чистить — просто замену пишут для ключа, а не для значения.
Как replace работает
Под капотом метод ищет все вхождения подстроки в исходной строке и собирает новую: на месте каждого найденного куска ставится новая подстрока, всё остальное переносится как есть. Поиск идёт по исходному тексту, поэтому новая подстрока не может быть обработана снова — рекурсии не бывает.
Отсюда и правило про замену на пустую строку: вхождение вырезается, а остальные куски склеиваются — ровно так же, как работает удаление. Отличие от обычной замены в том, что здесь ничего не подставляется, только вырезается.
Мини-практика: чистим список телефонов
Три телефона в разном оформлении. Приведите их к виду, в котором остаются только цифры и плюс, и выведите результат для каждого.
phones = ['+7 (912) 000-00-00', '8-800-555-35-35', 'тел.: 8 800 5553535']
for p in phones:
clean = p.replace(' ', '').replace('-', '').replace('(', '').replace(')', '').replace('тел.:', '')
print(clean)
+79120000000 88005553535 88005553535
Третий телефон пришёл со словом «тел.» — лишний кусок пришлось вырезать отдельной заменой. В реальных данных мусор всегда богаче, чем кажется на первый взгляд, и надёжнее не чистить каждый вариант, а разбирать строку по структуре. Для шаблонов сложнее простой замены есть регулярные выражения — там то же самое делается одним выражением с правилом.
Как заменить подстроку в Python: replace
replace — самый прямолинейный метод строк: берёт подстроку, заменяет её на другую и возвращает новую строку. Ничего хитрого, но три вещи стоит знать сразу. Первое: заменяются ВСЕ вхождения, если не сказать иное. Второе: регистр учитывается — replace не догадывается, что Error и error — одно и то же. Третье: метод ничего не находит и не сообщает об этом: если подстроки в строке нет, вы получите ту же строку без ошибки.
s = 'a-b-c-d'
print(s.replace('-', '+'))
print(s.replace('-', '+', 2))
a+b+c+d a+b+c-d
Третий аргумент — это ограничение по количеству замен, а не по позиции. s.replace('-', '+', 2) заменит первое и второе вхождения по порядку, третье и четвёртое останутся. Если нужно заменить только в начале строки — это уже другая задача, и replace для неё не годится: берите срез или startswith.
Цепочки replace: чистка чисел и дат
Типичная задача — привести к числу строку, в которой человек написал цену с пробелами, символом валюты и -разделителями. Один replace тут не справится, а вот цепочка работает. Порядок вызовов имеет значение: сначала убирают мусор, потом пробелы, и только в конце превращают в число.
price = '1 250.50 руб.'
clean = price.replace(' руб.', '').replace(' ', '')
print(clean)
print(float(clean))
1250.50 1250.5
Обратите внимание на вывод: float('1250.50') печатается как 1250.5 — это нормальное поведение float, а не ошибка. Если нужны ровно два знака после запятой, форматируйте при выводе: f'{value:.2f}'. И ещё: float() терпит пробелы вокруг числа, но не внутри — '1 250.50' без замены пробела даст ValueError. Это тот случай, когда лучше не гадать, а взять try/except и сообщить пользователю, что в поле цены попал лишний разделитель.
phone = '+7 (900) 123-45-67'
digits = phone
for ch in ' ()+-':
digits = digits.replace(ch, '')
print(digits)
print(len(digits))
79001234567 11
Цикл по набору символов — рабочий, но медленный способ: для каждого символа проход по всей строке. На коротких номерах это незаметно, на выгрузке из CRM в миллион строк — уже нет. Быстрее отфильтровать: ''.join(ch for ch in phone if ch.isdigit()). Оно и читается точнее: «оставь только цифры», а не «убери эти пять символов».
| Что нужно | Как написать | Замечание |
|---|---|---|
| Заменить все вхождения | s.replace('old', 'new') | Регистр учитывается |
| Заменить первые N | s.replace('old', 'new', N) | N — количество, не позиция |
| Убрать мусор из числа | float(s.replace(' ', '').replace(',', '.')) | Порядок замен важен |
| Оставить только цифры | ''.join(ch for ch in s if ch.isdigit()) | Один проход вместо цикла |
| Заменить без учёта регистра | s.lower().replace(old.lower(), new) | Меняет и найденное, и новое |
| Убрать подстроку целиком | s.replace('old', '') | Это и есть удаление |
Про replace и регулярные выражения стоит сказать отдельно, потому что это частый вопрос. replace работает с обычным текстом: если в подстроке есть специальные символы — «(», «+», «*» — они ищутся буквально. Замены по шаблону (d+, [а-я]+) через replace не сделать. Для таких задач есть re.sub — но это уже курс регулярных выражений, и тянуть его в базовый разбор строк я бы не стал.
И последнее, о чём стоит помнить: replace не работает в списках. Он есть у строки, и всё. Если в списке десять элементов и в каждом надо заменить подстроку — придётся либо пройти циклом с пересборкой списка, либо вспомнить про списковое включение из другого раздела. Для коротких списков цикл читается лучше, для длинных — быстрее включение.
Замена на пустую строку — это удаление: Python просто вырезает подстроку и склеивает края.
Сначала предскажи ответ в голове — это главный навык программиста.
print('а-а-а'.replace('-', '+'))
s = 'кот кот кот'
print(s.replace('кот', 'пёс', 2))
s = 'коткод'
print(s.replace('код', '', 1))
1. Что вернёт 'кот кот кот'.replace('кот', 'пёс')?
2. Что означает третий аргумент в s.replace('а', 'б', 2)?
3. Как «удалить» все пробелы из строки s?
4. Что произойдёт после text = 'кот' и вызова text.replace('кот', 'пёс') без присваивания?
5. Что вернёт replace, если искомой подстроки в строке нет?
6. Зачем в цепочке пишут несколько replace подряд?
7. Что вернёт 'аб'.replace('а', 'б').replace('б', 'а')?
8. Почему 'Кот и кот и КОТ'.replace('кот', 'пёс') меняет только одно слово?
Дана строка phone с телефоном в разном мусоре: пробелы, скобки и дефисы. Собери цепочку replace, которая оставит только номер без мусора, и выведи результат.
Как заменить подстроку в строке в Python?
Методом replace: s.replace('кот', 'пёс') вернёт новую строку, где все вхождения «кот» заменены на «пёс». Метод не меняет исходную строку — результат нужно присвоить: s = s.replace('кот', 'пёс').
Урок 1: неизменяемость строкКак заменить только первое вхождение подстроки?
Передать третьим аргументом лимит замен: s.replace('кот', 'пёс', 1). Замены идут слева направо и остановятся после первого совпадения, всё остальное останется как было.
Как удалить символ или подстроку из строки?
Заменить на пустую строку: s.replace(' ', '') уберёт все пробелы, s.replace('-', '', 1) — только первый дефис. Отдельного метода удаления у строк нет — замена на пустую строку и есть удаление.
Чем replace отличается от strip?
strip снимает символы только с краёв строки и по набору символов, replace меняет точную подстроку по всей длине, включая середину. Для чистки пробелов по краям берут strip, для правки текста внутри — replace.
Урок 6: stripКак убрать из строки все точки и запятые?
Заменой на пустую строку: s.replace('.', '').replace(',', ''). Метод удаления у строк нет, но замена на пустую строку делает ровно то же самое — вырезает вхождения и склеивает края.
Почему после replace ничего не изменилось?
Строки неизменяемы: метод вернул новую строку, но её не сохранили. Правильная запись — s = s.replace('кот', 'пёс'). Второй случай — подстрока не совпала: replace ищет буквально, без учёта регистра и смысла.
Урок 1: неизменяемость строкПонравился урок? Сошлитесь на него
«Замена на пустую строку — это удаление: Python просто вырезает подстроку и склеивает края.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Строки · Урок 6
strip: обрезаем пробелы и мусор
Пробелы по краям — самая частая грязь в данных: ввод пользователя, поля CSV, строки из файлов. Знакомимся с strip, lstrip и rstrip — и с аргументом-набором символов.
Строки · Урок 8
Поиск: find, rfind и in
Поиск в строке отвечает на три разных вопроса: «есть ли?», «где?» и «с чего начинается?». Разбираем in, find, rfind, startswith и endswith — и опасное значение -1, которое притворяется индексом.
Строки · Урок 1
Строки в Python: текст как данные
Строка — самый частый тип данных в реальных задачах: имена, города, сообщения. Знакомимся с типом str: кавычки, len, конкатенация и умножение — и узнаём, почему строку нельзя переписать на месте.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Циклы · Урок 16
Циклы и строки в Python: разбор текста на слова
Разбор текста начинается со split: строка превращается в список слов, цикл считает, ищет и собирает отчёт.
цикл по строке pythonpython перебор слов в строке
Множества · Урок 4
remove, discard и pop: удаление элементов множества
Три способа убрать элемент: remove падает на отсутствующем, discard молчит, pop достаёт произвольный. Один и тот же набор, три разные реакции на пустоту.
python удалить из множестваметоды множеств python
Строки · Урок 3
f-строки: вставить значение в текст
f-строка вставляет значение прямо в текст: f'Привет, {name}!' — без плюсов, скобок и str(). Внутри фигурных скобок работает любое выражение Python. Учимся читать и писать их свободно.
f строки pythonf строки в python