Вступление
Замена всех или n вхождений подстроки в заданной строке - довольно распространенная проблема манипуляций со строками и обработки текста в целом. К счастью, большинство этих задач упрощаются в Python благодаря огромному набору встроенных функций, включая эту.
Допустим, у нас есть строка, содержащая следующее предложение:
The brown-eyed man drives a brown car.
Наша цель - заменить слово "brown"
словом "blue"
:
The blue-eyed man drives a blue car.
В этой статье мы будем использовать replace()
а также функции sub()
и subn()
с шаблонами для замены всех вхождений подстроки из строки.
заменять()
Самый простой способ сделать это - использовать встроенную функцию
replace()
:
string.replace(oldStr, newStr, count)
Первые два параметра являются обязательными, а третий - необязательным.
oldStr
- это подстрока, которую мы хотим заменить на newStr
. Стоит
отметить, что функция возвращает новую строку с выполненным
преобразованием, не затрагивая исходную.
Давайте попробуем:
string_a = "The brown-eyed man drives a brown car."
string_b = string_a.replace("brown", "blue")
print(string_a)
print(string_b)
Мы выполнили операцию с string_a
, упаковали результат в string_b
и
распечатали их оба.
Этот код приводит к:
The brown-eyed man drives a brown car.
The blue-eyed man drives a blue car.
Опять же, строка в памяти, на string_a
указывает string_a, остается
неизменной. Строки в Python неизменяемы, что просто означает, что вы не
можете изменить строку. Однако вы можете повторно присвоить ссылочной
переменной новое значение.
Чтобы, казалось бы, выполнить эту операцию на месте , мы можем просто
переназначить string_a
себе после операции:
string_a = string_a.replace("brown", "blue")
print(string_a)
Здесь новая строка, сгенерированная методом replace()
присваивается
переменной string_a
Заменить n вхождений подстроки
А что, если мы не хотим изменять все вхождения подстроки? Что, если мы хотим заменить первые n ?
Вот тут и появляется третий параметр функции replace()
. Он
представляет количество подстрок, которые будут заменены. Следующий код
заменяет только первое вхождение слова "brown"
словом "blue"
:
string_a = "The brown-eyed man drives a brown car."
string_a = string_a.replace("brown", "blue", 1)
print(string_a)
И это печатает:
The blue-eyed man drives a brown car.
По умолчанию третий параметр настроен на изменение всех вхождений.
Вхождения подстроки в регулярных выражениях
Чтобы усугубить проблему, допустим, мы хотим не только заменить все
вхождения определенной подстроки, но и заменить все подстроки,
соответствующие определенному шаблону. Даже это можно сделать с
однострочником, с использованием регулярных выражений и модуля re
Регулярные выражения - сложная тема с широким спектром использования в информатике, поэтому мы не будем вдаваться в подробности в этой статье, но если вам нужно быстрое начало, вы можете ознакомиться с нашим руководством по регулярным выражениям в Python .
По сути, регулярное выражение определяет шаблон. Например, предположим,
что у нас есть текст о людях, владеющих кошками и собаками, и мы хотим
заменить оба термина словом "pet"
. Во-первых, нам нужно определить
шаблон, который соответствует обоим терминам, например - (cat|dog)
.
Использование функции sub ()
Разобравшись с шаблоном, мы собираемся использовать re.sub()
которая
имеет следующий синтаксис:
re.sub(pattern, repl, string, count, flags)
Первый аргумент - это шаблон, который мы ищем (строка или Pattern
),
repl
- это то, что мы собираемся вставить (может быть строкой или
функцией; если это строка, любые символы обратной косой черты в ней
будут обработано), а string
- это строка, в которой мы ищем.
Необязательными аргументами являются count
и flags
которые
указывают, сколько вхождений необходимо заменить, и флаги, используемые
для обработки регулярного выражения, соответственно.
Если шаблон не соответствует ни одной подстроке, исходная строка будет возвращена без изменений:
import re
string_a = re.sub(r'(cat|dog)', 'pet', "Mark owns a dog and Mary owns a cat.")
print(string_a)
Этот код печатает:
Mark owns a pet and Mary owns a pet.
Сопоставление с шаблоном без учета регистра
re.IGNORECASE
регистра, мы установим для параметра flag значение
re.IGNORECASE:
import re
string_a = re.sub(r'(cats|dogs)', "Pets", "DoGs are a man's best friend", flags=re.IGNORECASE)
print(string_a)
Теперь будет учитываться любая комбинация падежей "dogs"
. При
сопоставлении шаблона с несколькими строками, чтобы избежать его
копирования в нескольких местах, мы можем определить объект Pattern
У
них также есть sub()
с синтаксисом:
Pattern.sub(repl, string, count)
Использование объектов шаблона
Давайте определим Pattern
для кошек и собак и проверим пару
предложений:
import re
pattern = re.compile(r'(Cats|Dogs)')
string_a = pattern.sub("Pets", "Dogs are a man's best friend.")
string_b = pattern.sub("Animals", "Cats enjoy sleeping.")
print(string_a)
print(string_b)
Что дает нам результат:
Pets are a man's best friend.
Animals enjoy sleeping.
Функция subn ()
Также существует subn()
с синтаксисом:
re.subn(pattern, repl, string, count, flags)
Функция subn()
возвращает кортеж со строкой и количеством совпадений в
строке, которую мы искали:
import re
string_a = re.subn(r'(cats|dogs)', 'Pets', "DoGs are a mans best friend", flags=re.IGNORECASE)
print(string_a)
Кортеж выглядит так:
('Pets are a mans best friend', 1)
Объект Pattern
содержит аналогичную subn()
:
Pattern.subn(repl, string, count)
И он используется очень похожим образом:
import re
pattern = re.compile(r'(Cats|Dogs)')
string_a = pattern.subn("Pets", "Dogs are a man's best friend.")
string_b = pattern.subn("Animals", "Cats enjoy sleeping.")
print(string_a)
print(string_b)
Это приводит к:
("Pets are a man's best friend.", 1)
('Animals enjoy sleeping.', 1)
Заключение
Python предлагает простые и простые функции для обработки строк. Самый
простой способ заменить все вхождения данной подстроки в строке -
использовать функцию replace()
При необходимости re
стандартной библиотеки предоставляет более
разнообразный набор инструментов, который можно использовать для решения
более узких задач, таких как поиск шаблонов и поиск без учета регистра.