JavaScript RegEx (ИЛИ)
Регулярные выражения JavaScript (RegEx) предлагают мощные возможности для поиска шаблонов в строках. Один из ключевых элементов RegEx — оператор OR.
Регулярные выражения JavaScript (RegEx) предоставляют мощные возможности для поиска шаблонов в строках. Одним из ключевых компонентов RegEx является оператор OR, обозначаемый вертикальной чертой (|). Этот оператор позволяет включать несколько шаблонов в одно регулярное выражение, обеспечивая гибкий и эффективный поиск и обработку строк. В этом подробном руководстве мы рассмотрим использование оператора OR в JavaScript RegEx с практическими примерами для лучшего понимания.
Понимание оператора OR (|) в RegEx
Оператор OR в регулярных выражениях позволяет задавать несколько альтернатив для совпадения. Он особенно полезен, когда нужно найти один из нескольких возможных шаблонов.
Базовое использование оператора OR
Синтаксис оператора OR прост: символ | размещается между шаблонами, которые нужно найти.
В этом примере шаблон /cat|dog/ соответствует как "cat", так и "dog" в заданных строках.
Приоритет чередования: почему почти всегда нужны скобки
Это главная ловушка при работе с |. Оператор OR имеет очень низкий приоритет — ниже, чем у любого другого оператора регулярных выражений. Это означает, что | разбивает всё выражение на альтернативы вплоть до окружающих разделителей или ближайших охватывающих скобок.
Таким образом, /cat|concatenate/ означает не «cat, за которым опционально следует concatenate», а: найти весь шаблон cat ИЛИ весь шаблон concatenate. Аналогично /^cat|dog$/ читается как (^cat)|(dog$) — «начинается с cat» ИЛИ «заканчивается на dog» — что редко соответствует намерению автора.
Чтобы ограничить чередование только частью шаблона, оберните альтернативы в скобки.
Привязка всего шаблона с помощью ^ и $ — распространённый приём, используемый вместе с группированным чередованием. Подробнее см. Якоря: начало и конец строки.
Порядок имеет значение: побеждает первое совпадение
Движок регулярных выражений проверяет альтернативы слева направо и останавливается на первой, которая совпала в текущей позиции. Он не ищет наиболее длинное совпадение — только первое подходящее. Поэтому порядок альтернатив имеет значение.
Практическое правило: указывайте более длинные или специфичные альтернативы перед более короткими, если они имеют общий префикс.
Группировка с помощью скобок
Скобки () группируют части регулярного выражения так, чтобы квантификаторы и другие операторы применялись ко всей группе, а также захватывают совпавший текст для дальнейшего использования (см. Захватывающие группы). Это необходимо, когда нужно, чтобы OR охватывал только фрагмент более крупного шаблона.
Здесь квантификатор s? применяется ко всей группе (cat|dog), поэтому шаблон соответствует "cat", "cats", "dog" и "dogs". Квантификатор ? и его аналоги рассматриваются в разделе Квантификаторы +, * и {n}.
Практические примеры
Сопоставление различных расширений файлов
Предположим, вам нужно проверить имена файлов с различными расширениями: .jpg, .png или .gif.
В этом примере шаблон /\.(jpg|png|gif)$/ соответствует именам файлов, заканчивающимся на ".jpg", ".png" или ".gif". Ведущий \. соответствует буквальной точке, группа (jpg|png|gif) — это чередование, а $ привязывает совпадение к концу строки.
Проверка номеров телефонов
Рассмотрим сценарий, в котором нужно проверить различные форматы номеров телефонов.
Разберём шаблон /(\+\d{1,2}\s?)?(\(\d{3}\)|\d{3})[-.\s]?\d{3}[-.\s]?\d{4}/ по частям:
(\+\d{1,2}\s?)?— необязательный код страны: знак+, одна или две цифры, затем необязательный пробел. Завершающий?делает всю группу необязательной.(\(\d{3}\)|\d{3})— чередование: три цифры в скобках(123)или три цифры без скобок123. Обратите внимание, что\(и\)— это буквальные скобки, тогда как внешние неэкранированные()выполняют группировку.[-.\s]?— необязательный разделитель: дефис, точка или пробельный символ. (Это классы символов.)\d{3}— три цифры.[-.\s]?— ещё один необязательный разделитель.\d{4}— последние четыре цифры.
Чистое чередование против необязательных подшаблонов
Распространённая ошибка — воспринимать color|colour так, будто u является необязательным. Это не так — здесь используется чистое чередование двух полных слов.
Когда альтернативы отличаются лишь одним символом (или короткой последовательностью), идиоматичный и более эффективный подход — использовать квантифицированный необязательный подшаблон, а не чередование. Квантификатор ? делает предшествующий u необязательным:
Используйте чередование (|), когда варианты представляют собой принципиально разные строки (cat|dog); используйте ?, когда одна форма — это другая плюс необязательный фрагмент (colou?r).
Комбинирование оператора OR с другими метасимволами
Возможности оператора OR расширяются при его использовании вместе с другими метасимволами регулярных выражений: * (ноль или более), + (один или более), ? (ноль или один) и {} (ровно n раз).
Пример с квантификаторами
Шаблон /\b(cat|dog)s?\b/ находит слова "cat", "cats", "dog" и "dogs" как целые слова, используя метасимвол границы слова \b.
Расширенный пример с несколькими условиями
Два формата дат ниже — D-M-YYYY и YYYY-M-D — используют одинаковые разделители и количество цифр, поэтому регулярное выражение не может отличить порядок день-месяц по форме. Что оно может различить — это где находится четырёхзначный год: в конце для одного формата и в начале для другого.
Этот шаблон соответствует датам как в формате с днём первым (12-31-2023, 31-12-2023), так и в формате с годом первым (2023-12-31). Обратите внимание, что 31-12-2023 действительно совпадает — это вполне допустимая строка \d{1,2}-\d{1,2}-\d{4}, и первая альтернатива её принимает.
Важная тонкость: поскольку | имеет наименьший приоритет, ^ привязан только к первой альтернативе, а $ — только ко второй. Чтобы привязать обе альтернативы, сгруппируйте их:
Использование чередования с match(), matchAll() и replace()
test() лишь сообщает, совпал ли шаблон. Чтобы извлечь или преобразовать совпавший текст, комбинируйте чередование с захватывающими группами и строковыми методами match(), matchAll() и replace().
match() (без флага g) возвращает первое совпадение вместе с каждой захватывающей группой:
С флагом g метод match() возвращает все совпадения в виде array, а matchAll() даёт итератор объектов полного совпадения:
replace() позволяет переписывать каждую альтернативу. Здесь мы приводим британское и американское написание к единому варианту:
Заключение
Освоение оператора OR в регулярных выражениях JavaScript открывает широкий спектр возможностей для эффективного и гибкого поиска шаблонов. Понимая, как использовать оператор OR в сочетании с другими возможностями RegEx, вы сможете создавать мощные и гибкие шаблоны для решения сложных задач поиска и обработки строк.
Практика
Перед ответом обдумайте каждый вариант. Помните, что каждый из приведённых вариантов является синтаксически корректным регулярным выражением — вопрос в том, что именно каждое из них находит:
/cat|dog/— чистое чередование с использованием|; находит "cat" или "dog" в любом месте строки. Верно./(cat|dog)/— то же чередование, обёрнутое в захватывающую группу; группа не меняет того, что находится, а лишь захватывает совпадение. Верно./cat|dogs/— синтаксически верно, но вторая альтернатива — "dogs" (сs), поэтому слово "dog" без окончания никогда не будет найдено. Неверно для данного вопроса./cat||dog/— пустая альтернатива между двумя символами|соответствует пустой строке, поэтому это выражение найдёт почти всё, включая строки без слов "cat" или "dog". Неверно./(cat|dog)s/— обязательныйsпосле группы означает, что шаблон находит "cats" или "dogs", но не "cat" или "dog". Неверно./cat|do g/— пробел — это буквальный символ, поэтому вторая альтернатива — "do g" (с пробелом), а не "dog". Неверно.