REGEXP_REPLACE() в SQL — замена текста по регулярному выражению

REGEXP_REPLACE заменяет части строки, совпавшие с регулярным выражением, на заданный текст. Для аналитика это главный инструмент чистки данных: убрать всё, кроме цифр, из телефона, схлопнуть лишние пробелы, замаскировать email. В PostgreSQL по умолчанию заменяется только первое совпадение — для всех нужен флаг 'g'; в MySQL 8+ заменяются все вхождения сразу. В SQLite встроенной функции нет.

Синтаксис

REGEXP_REPLACE(строка, шаблон, замена [, флаги])

Примеры использования

Пример 1: Только цифры из телефона

SELECT phone,
       REGEXP_REPLACE(phone, '\D', '', 'g') AS digits
FROM users
LIMIT 3;

Результат:

phone              | digits
+7 (999) 123-45-67 | 79991234567
8-800-555-35-35    | 88005553535

Пример 2: Схлопнуть повторяющиеся пробелы

SELECT comment,
       REGEXP_REPLACE(comment, '\s+', ' ', 'g') AS clean
FROM events
LIMIT 2;

Результат:

comment       | clean
хочу    Pro   | хочу Pro
всё    ясно   | всё ясно

Пример 3: Маскировка email через обратные ссылки

SELECT email,
       REGEXP_REPLACE(email, '(.).+(@.+)', '\1***\2') AS masked
FROM users
LIMIT 3;

Результат:

email          | masked
anna@yandex.ru | a***@yandex.ru
ivan@ozon.ru   | i***@ozon.ru
Порешать SQL-задачи в тренажёре →

Типичная ошибка

Главная ловушка — в PostgreSQL без флага 'g' заменяется только первое совпадение, а в MySQL 8+ по умолчанию все. Обратные ссылки на группы пишутся как \1, \2. Регулярки заметно медленнее обычного REPLACE, поэтому на больших таблицах их не гонят по колонкам без нужды. В SQLite функции нет без подключаемого расширения.

Где спрашивают на собеседовании

Классическая задача на чистку и нормализацию строк на собесе — рядом идут TRIM, LOWER и обычный REPLACE для простых, не-regex случаев.

FAQ: частые вопросы про REGEXP_REPLACE

Чем REGEXP_REPLACE отличается от REPLACE?

REPLACE ищет и меняет буквальную подстроку, без шаблонов. REGEXP_REPLACE работает по регулярному выражению, поэтому справляется с переменными паттернами (любые цифры, пробелы, группы). REGEXP мощнее, но медленнее, так что для простой замены фиксированного текста берут REPLACE.

Почему заменяется только первое вхождение?

В PostgreSQL по умолчанию REGEXP_REPLACE меняет только первое совпадение — чтобы заменить все, добавьте флаг 'g': REGEXP_REPLACE(col, pattern, repl, 'g'). В MySQL 8 наоборот, по умолчанию заменяются все вхождения.

Работает ли REGEXP_REPLACE в SQLite?

В стандартной сборке SQLite встроенной REGEXP_REPLACE нет — нужна загружаемая функция/расширение или функция, определённая в приложении. Для простых замен без шаблонов используйте обычный REPLACE, который есть везде.

Вопросы с собеседований по теме

Смежные темы SQL

Строковые функции · null-handling

Другие функции SQL

COALESCE · NULLIF · COUNT · SUBSTR · CAST · CONCAT

Открыть SQL-тренажёр (565 задач) →