Замена через 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> снимает двусмысленность перед цифрой.
Проверьте себя
1. Сколько совпадений по умолчанию заменяет re.sub?
AТолько первое
BВсе найденные совпадения
CТолько последнее
DЗависит от длины строки
2. Как в строке-замене вставить текст, захваченный первой группой?
A$1
B\1
C%1
Dgroup(1)
3. Зачем нужна форма \g<1> вместо \1?
AОна работает быстрее
BОна снимает двусмысленность, когда сразу после ссылки идёт цифра (\g<1>0)
CЭто единственный способ сослаться на группу
DОна ссылается на группу с конца
Поддержать проект