Замена через sub: группы \1 и \g<name>
Заменяем совпадения новым текстом и подставляем в замену захваченные части.
re.sub(pattern, replacement, text) заменяет все совпадения паттерна на строку-замену и возвращает новый текст.
Простая замена
re.sub находит все совпадения и заменяет их. Спрячем все числа под решётку:
import re
print(re.sub(r"\d+", "#", "Заказ 12, позиций 345"))
Вывод:
Заказ #, позиций #
Каждая группа цифр заменилась на #. По умолчанию sub заменяет все совпадения (можно ограничить аргументом count).
Ссылки на группы в замене
Самое мощное в sub — в строку-замену можно вставлять захваченные группы через \1, \2. Переформатируем дату из ISO в привычный вид:
import re
text = "2024-06-14"
print(re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\3.\2.\1", text))
Вывод:
14.06.2024
В замене \3.\2.\1 мы переставили группы: день, месяц, год — и поменяли разделитель. Замену тоже пишут в сырой строке r"...", чтобы \1 не воспринялось как спецсимвол.
Ссылки по имени \g<name>
С именованными группами в замене используют синтаксис \g<имя> — это читаемее, чем номера:
import re
text = "14/06/2024"
pattern = r"(?P<day>\d{2})/(?P<month>\d{2})/(?P<year>\d{4})"
print(re.sub(pattern, r"\g<year>-\g<month>-\g<day>", text))
Вывод:
2024-06-14
Форма \g<имя> работает и для номеров (\g<1>) — это нужно, когда после ссылки идёт цифра: \g<1>0 однозначно значит «группа 1, затем 0», а \10 было бы прочитано как «группа 10».
Практика: нормализация
Частая задача — схлопнуть лишние пробелы. Заменяем любые их группы на один:
import re
print(re.sub(r"\s+", " ", "много лишних\t\tпробелов").strip())
Вывод:
много лишних пробелов
Итог
re.sub(pattern, repl, text)заменяет все совпадения и возвращает новую строку.- В замене доступны группы:
\1,\2по номеру и\g<имя>по имени. - Замену тоже пишите в сырой строке
r"..."; форма\g<1>снимает двусмысленность перед цифрой.