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

1. Что такое чередование

Чередование означает использование|в регулярном выражении для представления логической связи «или». Оно позволяет сопоставить один из нескольких возможных шаблонов.

cat|dog

Этот шаблон будет соответствовать "cat" или "dog".

2. Что такое ветвление

Ветвление означает, что когда движок регулярных выражений при сопоставлении встречает точку чередования, он пробует разные пути сопоставления. Когда один путь не удаётся, движок выполняет возврат и пробует другие возможные пути.


Анализ принципа

Оператор чередования|Как это работает

  1. Механизм регулярных выражений сканирует|слева направо по альтернативам, разделённым |
  2. Пытается сопоставить первую альтернативу; при успехе останавливается
  3. Если первая альтернатива не совпадает, пытается сопоставить вторую альтернативу
  4. И так далее, пока не будет найдено совпадение или не будут перепробованы все альтернативы

Группировка и альтернация

Альтернация часто сочетается с группировкой()чтобы ограничить область действия альтернации:

Пример

gr(a|e)y

Этот шаблон будет соответствовать "gray" или "grey".

Ветвление и откат

Когда механизм регулярных выражений встречает точку альтернации:

  1. Запомните текущую позицию (создайте контрольную точку)
  2. Попробуйте первую ветвь
  3. Если это не сработает, вернитесь к контрольной точке
  4. Попробуйте следующую ветвь
  5. Повторяйте, пока не будет успеха или пока не будут опробованы все ветви

Практические примеры

Базовый пример альтернации

Пример

// Сопоставить несколько форматов даты
const datePattern = /\b(January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}\b/;

console.log(datePattern.test("March 15, 2023")); // true
console.log(datePattern.test("Sept 10, 2022"));  // false (сокращение не совпадает)

Пример группированной альтернации

Пример

import re

# Сопоставить американское или британское написание
pattern = r"colou?r|color"
text = "The color is red and the colour is blue"

matches = re.findall(pattern, text)
print(matches)  # Вывод: ['color', 'colour']

Пример сложного ветвления

Пример

// Сопоставление нескольких форматов телефонных номеров
String phonePattern = "(\\(\\d{3}\\) ?|\\d{3}[-.]?)\\d{3}[-.]?\\d{4}";

String[] testNumbers = {
    "(123)456-7890",
    "123.456.7890",
    "123-456-7890",
    "1234567890"
};

for (String number : testNumbers) {
    System.out.println(number.matches(phonePattern));  // Все выходные значения true
}

Расширенное применение

Советы по оптимизации производительности

  1. Сначала размещайте часто используемые варианты: поместите наиболее вероятный совпадающий вариант в начало

    (common|uncommon|rare)  # 优化顺序
  2. Избегайте избыточных ветвлений:

    (a|ab|c)  # 不好
    (ab?|c)   # 更好
  3. Используйте незахватывающие группы: когда захватывающие группы не нужны

    (?:pattern1|pattern2)

Реальные сценарии применения

  1. Анализ логов: сопоставление нескольких форматов сообщений об ошибках
  2. Валидация форм: принимать несколько допустимых форматов ввода
  3. Обработка текста: поиск синонимов или вариантов написания
  4. Сопоставление маршрутов: маршрутизация URL в веб-фреймворках
Другие расширения