Re.sub: примеры (PYTHON)
re.sub(pattern, repl, string, count, flags): strОписание функции re.sub
Функция re.sub из модуля re языка Python предназначена для замены вхождений шаблона регулярного выражения в строке на указанную замену. Применение этой функции распространено при обработке текстов, очистке данных, преобразовании форматов строк.
Основные аргументы функции:
- pattern: строка или скомпилированное регулярное выражение, задающее шаблон для поиска.
- repl: строка или функция, определяющая замену для найденных вхождений. В строке можно использовать обратные ссылки (например,
\1). - string: исходная строка, в которой выполняется поиск и замена.
- count: необязательный целочисленный аргумент, ограничивающий максимальное количество замен (по умолчанию 0, что означает замену всех вхождений).
- flags: флаги, изменяющие поведение регулярного выражения (например,
re.IGNORECASEдля игнорирования регистра).
Возвращаемое значение: строка, полученная после выполнения всех замен. Если совпадений не найдено, возвращается исходная строка.
Примеры использования re.sub
Простая замена цифр на символ 'X':
import re
result = re.sub(r'\d', 'X', 'a1b2c3')
print(result)aXbXcX
Использование обратной ссылки в строке замены для дублирования найденной группы:
result = re.sub(r'(\d+)', r'\1-\1', 'abc123def456')
print(result)abc123-123def456-456
Замена с ограничением количества замен (count=2):
result = re.sub(r'\d', 'X', 'a1b2c3d4', count=2)
print(result)aXbXc3d4
Использование флага re.IGNORECASE для регистронезависимой замены:
result = re.sub(r'python', 'Java', 'Python is python', flags=re.IGNORECASE)
print(result)Java is Java
Передача функции в качестве аргумента repl для преобразования найденных чисел в квадрат:
def square(match):
num = int(match.group())
return str(num * num)
result = re.sub(r'\d+', square, '2 and 5')
print(result)4 and 25
Похожие функции в Python
Для замены подстрок в Python также применяются:
- str.replace(): простая замена фиксированной строки без использования регулярных выражений. Работает быстрее для элементарных случаев.
- re.subn(): аналогична
re.sub, но возвращает кортеж из новой строки и количества выполненных замен. - str.translate(): эффективное преобразование отдельных символов с помощью таблицы перевода.
Выбор между re.sub и str.replace зависит от необходимости использования сложных шаблонов: для простых замен подходит str.replace, а для работы с паттернами - re.sub.
Аналоги функции в других языках
В разных языках программирования существуют похожие методы:
JavaScript: метод replace() строки с поддержкой регулярных выражений.
let str = 'a1b2c3';
let result = str.replace(/\d/g, 'X');
console.log(result);aXbXcX
PHP: функция preg_replace() для замены по регулярному выражению.
$str = 'a1b2c3';
$result = preg_replace('/\d/', 'X', $str);
echo $result;aXbXcX
Java: метод replaceAll() класса String.
String str = "a1b2c3";
String result = str.replaceAll("\\d", "X");
System.out.println(result);aXbXcX
Golang: функция ReplaceAllString() из пакета regexp.
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`\d`)
result := re.ReplaceAllString("a1b2c3", "X")
fmt.Println(result)
}aXbXcX
Отличия от Python-версии могут заключаться в синтаксисе шаблонов, способе передачи флагов и наличии дополнительных параметров.
Типичные ошибки при использовании re.sub
Ошибка из-за неправильного экранирования обратных ссылок в строке замены при использовании сырых строк:
# Неправильно: использование одного обратного слеша
result = re.sub(r'(\d+)', '\1', 'test123') # Ожидается '123', но будет ошибка или неверный результат# Правильно: использование сырых строк для обратных ссылок
result = re.sub(r'(\d+)', r'\1', 'test123')
print(result)test123
Попытка использовать функцию замены с некорректным числом аргументов:
def repl_func():
return "X"
try:
result = re.sub(r'\d', repl_func, 'a1b2')
except TypeError as e:
print(f"Ошибка: {e}")Ошибка: repl_func() takes 0 positional arguments but 1 was given
Использование re.sub с большим количеством замен на длинных строках без учета производительности:
# Медленный пример на большой строке
import time
long_str = 'a' * 1000000 + '1'
start = time.time()
result = re.sub(r'\d', 'X', long_str)
print(f"Затраченное время: {time.time() - start:.2f} сек")Для оптимизации часто компилируют регулярное выражение заранее с помощью re.compile.
Изменения в функции re.sub
В последних версиях Python значительных изменений в функции re.sub не происходило. Начиная с Python 3.7, шаблоны регулярных выражений и строки замены кэшируются для повышения производительности. В Python 3.11 были внесены общие оптимизации в модуль re, которые могут ускорять выполнение re.sub в некоторых сценариях.
Важным изменением в Python 3.7 стало то, что пустые совпадения для шаблона в результате разбиения заменяются только тогда, когда они не примыкают к предыдущему пустому совпадению. Это повлияло на поведение re.sub в крайних случаях с нулевой длиной совпадения.
Расширенные примеры использования re.sub
Конвертация формата даты из 'dd/mm/yyyy' в 'yyyy-mm-dd':
date_str = '25/12/2023'
result = re.sub(r'(\d{2})/(\d{2})/(\d{4})', r'\3-\2-\1', date_str)
print(result)2023-12-25
Удаление повторяющихся слов в строке:
text = 'Это повтор повтор слов слов.'
result = re.sub(r'\b(\w+)( \1\b)+', r'\1', text)
print(result)Это повтор слов.
Экранирование всех специальных символов в строке для использования в регулярном выражении:
import re
text = 'Пример. Со [спец] символами.'
escaped = re.sub(r'([\\\\.\[\]\{\}\\(\\)\\*\\+\\?\\|\\^\\$])', r'\\\1', text)
print(escaped)Пример\. Со \[спец\] символами\.
Разделение CamelCase на отдельные слова с пробелами:
def spaces(match):
return ' ' + match.group(1).lower()
camel = 'CamelCaseString'
result = re.sub(r'([A-Z])', spaces, camel).strip()
print(result)camel case string
Замена чисел на их текстовое представление с помощью функции-замены:
def number_to_text(match):
num_map = {'1': 'один', '2': 'два', '3': 'три'}
return num_map.get(match.group(), match.group())
result = re.sub(r'\d', number_to_text, 'У меня 2 яблока и 1 апельсин')
print(result)У меня два яблока и один апельсин
Обработка HTML-тегов: удаление всех тегов, оставляя только текст:
html = '<div>Текст <span>с тегами</span>.</div>'
clean = re.sub(r'<[^>]*>', '', html)
print(clean)Текст с тегами.