Регулярные выражения - Группировка и ссылки

В регулярных выражениях,группировка(Группировка) позволяет рассматривать несколько символов как единое целое, подобно скобкам в математике. Группировка имеет две основные цели:

  1. Рассматривать несколько символов как единое целое: Вы можете применять квантификаторы к этому целому (например,*、+、?、{n})
  2. Захватывать совпавшее содержимое: Позже вы можете ссылаться на эту часть совпавшего содержимого или извлекать её

Базовый синтаксис

Используйте круглые скобки()для создания групп:

(expression)

Например,(ab)+может совпадать с "ab", "abab", "ababab" и т. д., но не может совпадать с "a" или "b".


Типы групп

В регулярных выражениях существует несколько различных типов групп:

1. Захватывающая группа

Наиболее распространённая форма группировки; она захватывает совпавшее содержимое и присваивает номер (начиная с 1).

Пример

(\d{4})-(\d{2})-(\d{2})# Сопоставить формат даты YYYY-MM-DD

Это выражение создаёт 3 группы:

  • Группа 1: 4-значный год
  • Группа 2: 2-значный месяц
  • Группа 3: 2-значный день

2. Незахватывающая группа

Используйте(?:expression)синтаксис, означающий только группировку без захвата.

Пример

(?:Mr|Ms|Mrs)\. (\w+)# Совпадение"Mr. Smith"но захватывается только"Smith"

3. Именованная захватывающая группа

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

Пример на Python:

Пример

(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})

Пример на JavaScript:

Пример

(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})

Обратные ссылки на группы

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

1. Обратная ссылка

Чтобы сослаться на более раннюю группу внутри регулярного выражения, используйте\digitсинтаксиса:

Пример

(\w+) \1# Найти повторяющиеся слова, например"hello hello"

Этот шаблон соответствует двум одинаковым словам, разделённым пробелом.

2. Именованная обратная ссылка

Для именованных групп можно ссылаться на них по имени:

Пример

(?P<word>\w+) (?P=word)# Синтаксис Python
\k<word># Синтаксис JavaScript

3. Ссылка в замене

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

Пример на Python:

Пример

import re
text = "2023-05-15"
new_text = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', text)
# Результат: "05/15/2023"

Пример на JavaScript:

Пример

let text = "2023-05-15";
let newText = text.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2/$3/$1');
// Результат: "05/15/2023"

Примеры практического применения

Пример 1: Сопоставление HTML-тегов

Пример

<([a-z][a-z0-9]*)\b[^>]*>.*?</\1>

Этот шаблон может сопоставлять парные HTML-теги (такие как<div>...</div>), где:

  • ([a-z][a-z0-9]*)Захватывает имя тега
  • \1Ссылается на ранее захваченное имя тега для обеспечения согласованности

Пример 2: Обнаружение повторяющихся слов

Пример

\b(\w+)\b\s+\1\b

Может находить повторяющиеся подряд слова в тексте.

Пример 3: Преобразование формата даты

Код Python:

Пример

import re

date = "2023-12-25"
# Преобразовать YYYY-MM-DD в DD/MM/YYYY
new_date = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\3/\2/\1', date)
print(new_date)  # Вывод: 25/12/2023

Продвинутые применения группировки

1. Условное сопоставление

Некоторые движки регулярных выражений поддерживают условное сопоставление на основе групп:

Пример

(?(1)true-pattern|false-pattern)

Указывает, что если группа 1 совпала, сопоставить true-pattern; в противном случае сопоставить false-pattern.

2. Сбалансированные группы (расширенная возможность)

Используется для сопоставления вложенных структур (например, скобок); требует поддержки определённых движков регулярных выражений.


Распространённые проблемы и подводные камни

  1. Чрезмерное использование групп: ненужные группы могут влиять на производительность

    • Плохой пример:(a)|(b)(Если захват не нужен, используйте(?:a|b))
  2. Путаница с нумерацией групп:

    • Номера групп начинаются с 1 в порядке открывающих круглых скобок
    • Незахватывающие группы не нумеруются
  3. Проблемы с жадным сопоставлением:

    <(.*)>  # will greedily match up to the last >

    Следует использовать:

    <(.*?)>  # non-greedy matching

Практические задания

  1. Напишите регулярное выражение для сопоставления повторяющихся имён пользователей электронной почты (например,[email protected];[email protected])
  2. Преобразуйте формат телефонного номера из(123) 456-7890в123-456-7890
  3. Извлечь все атрибуты из HTML-тегов (таких как<img src="..." alt="...">src и alt внутри)

Сводка ключевых моментов

Концепция Синтаксис Назначение
Захватывающая группа (pattern) Захватывает совпавшее содержимое и присваивает номер
Незахватывающая группа (?:pattern) Группы без захвата
Именованная захватывающая группа (?P<name>pattern) (Python) Присваивает имя группе
Обратная ссылка \1, \2ожидание Ссылается на ранее совпавшую группу
Именованная обратная ссылка (?P=name) (Python) Ссылается на группу по имени
Ссылка в замене $1, $2или\1, \2 Ссылается на группы в строках замены

Освоение группировки и ссылок в регулярных выражениях позволяет вам:

  • Создавать более сложные шаблоны сопоставления
  • Извлекать и обрабатывать определённые части строк
  • Реализовывать интеллектуальное преобразование строк
  • Проверять сложные текстовые структуры
Другие расширения