Создать URL
Генератор Правила транслитерации Как сделать ЧПУ Блог Вопросы и ответы Создать URL
Инструменты

Регулярные выражения для очистки адресов

Транслитерация превращает буквы, а порядок в адресе наводят регулярные выражения: убирают лишние символы, схлопывают повторы, обрезают края. Разбираем рабочий набор паттернов.

Почему порядок операций важен

Очистка адреса — это последовательность из нескольких шагов, и применение их в неверном порядке даёт неожиданный результат. Общая последовательность разобрана на примере функции транслита в статье про PHP, JavaScript и Python: сначала замена букв по таблице, затем удаление лишних символов, затем схлопывание разделителей, и только в конце — обрезка краёв.

Удаление знаков препинания без замены на разделитель

Некоторые символы — кавычки, апострофы, точки в сокращениях — должны исчезать полностью, а не превращаться в дефис. Если их не убрать заранее, они попадут под общее правило замены посторонних символов и создадут лишний разделитель там, где его быть не должно.

Паттерн:  /['"«»`’]+/g
Пример:   ООО «Садовый мир» → OOO Sadovyj mir (кавычки исчезли, не оставив следа)

Замена всего постороннего на разделитель

После того как «тихие» символы удалены, всё остальное, что не входит в латиницу и цифры, превращается в разделитель — этот паттерн и делает основную работу очистки.

Паттерн:  /[^a-z0-9]+/g
Замена:   на выбранный разделитель ('-' или '_')

Именно этот шаг превращает пробелы, эмодзи и оставшиеся спецсимволы, разобранные в статье про спецсимволы и эмодзи в заголовках, в единообразные дефисы.

Схлопывание повторяющихся разделителей

После предыдущего шага в строке могут оказаться несколько разделителей подряд — например, если рядом стояли два разных символа, каждый из которых заменился на дефис.

Паттерн:  /-{2,}/g
Замена:   на один дефис

Для более общего варианта, работающего с любым выбранным разделителем, а не только дефисом, паттерн строится динамически с учётом текущего символа-разделителя — важно экранировать его в регулярном выражении, если это символ вроде точки, у которого есть особый смысл в синтаксисе регулярных выражений.

Частая ошибка в этом шаге. Паттерн вида /--/g заменяет только пары из ровно двух дефисов и не сработает на строке с тремя дефисами подряд. Квантификатор {2,} означает «два или больше» и покрывает любое количество повторов правильно.

Обрезка разделителей по краям строки

Последний шаг — убрать разделитель, если он оказался в самом начале или в самом конце адреса, что часто случается после удаления первого или последнего слова фразы.

Паттерн:  /^-+|-+$/g
Замена:   на пустую строку

Вертикальная черта в паттерне означает «или»: выражение находит разделители либо в начале, либо в конце строки и убирает оба случая одним проходом.

Полный пример последовательности на JavaScript

function cleanUrl(text, sep = '-') {
  const escaped = sep === '-' ? '\\-' : sep;
  return text
    .replace(/['"«»`’]+/g, '')                              // тихое удаление
    .replace(/[^a-z0-9]+/g, sep)                              // замена на разделитель
    .replace(new RegExp(`[${escaped}]{2,}`, 'g'), sep)        // схлопывание
    .replace(new RegExp(`^[${escaped}]+|[${escaped}]+$`, 'g'), ''); // обрезка краёв
}

Эта последовательность — ровно то, что происходит внутри пакетного режима генератора на этом сайте, только записанное явно шаг за шагом.

Тестовые случаи для проверки паттернов

ВходОжидаемый результат
«Тест» — пример!test-primer
—Пример—primer
Слово с пробеламиslovo-s-probelami
А---Бa-b

Чек-лист

  1. Сначала «тихое» удаление кавычек и апострофов, затем замена остального на разделитель.
  2. Схлопывание использует квантификатор «два и более», а не фиксированное число повторов.
  3. Обрезка краёв выполняется последним шагом, после всех замен.
  4. Специальные символы разделителя экранируются, если для него выбран знак вроде точки.
  5. Набор паттернов проверен на тестовых случаях с разными комбинациями символов.

Производительность регулярных выражений на больших объёмах

При обработке каталога в десятки тысяч строк регулярное выражение стоит компилировать один раз вне цикла, а не создавать заново для каждой строки — в языках вроде JavaScript и Python повторная компиляция одного и того же паттерна заметно замедляет обработку на больших объёмах, хотя для одиночного адреса разница незаметна.

Пограничные случаи, которые стоит протестировать отдельно

  • Строка, состоящая только из посторонних символов, — результат должен быть пустой строкой, а не набором дефисов.
  • Одно единственное слово без пробелов — обрезка краёв не должна его повредить.
  • Разделитель в самом начале и в самом конце одновременно.
  • Пустая строка на входе — функция не должна выбрасывать ошибку.

Частые вопросы

В каком порядке применять регулярные выражения при очистке адреса?

Сначала тихое удаление кавычек и апострофов без замены на разделитель, затем замена всех остальных посторонних символов на разделитель, затем схлопывание повторов и в конце — обрезка краёв строки.

Почему после замены символов в адресе остаются двойные дефисы?

Потому что шаг схлопывания повторов не выполнен или использует неверный квантификатор. Паттерн должен ловить любое количество повторов подряд, а не только пары.

Нужно ли экранировать символ разделителя в регулярном выражении?

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

Готовый адрес можно собрать прямо сейчас: откройте генератор ЧПУ — он транслитерирует фразу по таблице Яндекса, уберёт служебные слова и покажет длину адреса.

Читайте также