sub с функцией и split по регулярке
Делаем замену по произвольной логике и разбиваем строку по сложным разделителям.
Вторым аргументом re.sub может быть функция: её вызывают для каждого совпадения, и она возвращает строку-замену.
Замена-функция
Когда замена зависит от самого совпадения (а не фиксированная строка), вместо текста передают функцию. Она получает объект Match и возвращает строку. Удвоим все числа в тексте:
import re
def double(m):
return str(int(m.group()) * 2)
print(re.sub(r"\d+", double, "купить 2 по 10 и 3 по 50"))
Вывод:
купить 4 по 20 и 6 по 100
Для каждого числа вызвалась double: она превратила текст в число, умножила и вернула обратно строкой. Так делают вычисляемые замены, которые невозможно описать одной строкой.
Ещё пример: капитализация
Сделаем первую букву каждого слова заглавной — найдём первую букву слова и заменим функцией:
import re
def up(m):
return m.group().upper()
print(re.sub(r"\b\w", up, "привет дивный новый мир"))
Вывод:
Привет Дивный Новый Мир
Паттерн \b\w ловит первую букву каждого слова (граница слова + один символ-слово), а функция переводит её в верхний регистр.
split — разбиение по шаблону
Метод str.split умеет делить только по фиксированной строке. re.split делит по шаблону — это спасает, когда разделители разные:
import re
print(re.split(r"[,;]\s*", "яблоко, груша; слива,банан"))
Вывод:
['яблоко', 'груша', 'слива', 'банан']
Разделителем выступила «запятая или точка с запятой, за которой могут идти пробелы». Обычный split так не умеет.
split с захватом разделителей
Если разделитель в паттерне взять в группу, re.split сохранит разделители в результате — иногда это нужно:
import re
print(re.split(r"(\d+)", "abc123def456"))
Вывод:
['abc', '123', 'def', '456', '']
Текст разбился по числам, но и сами числа попали в список (последний элемент — пустая строка, т.к. строка кончилась числом).
Итог
- Вторым аргументом
subможет быть функция — для вычисляемых замен. - Функция получает
Matchи возвращает строку-замену. re.split(pattern, text)делит строку по шаблону-разделителю.- Группа в паттерне split сохраняет разделители в результате.