Регулярные выражения в Python: полный набор символов и их использование

Раздел: Текст -> Регулярные выражения

Основные символы регулярных выражений Python

Регулярные выражения (regex) в Python реализованы в модуле re. Каждый символ в шаблоне может быть либо обычным (ищет себя), либо специальным (метасимволом). Основной подход - использовать сырые строки (r'...'), чтобы избежать двойного экранирования.

Цель: быстро и гибко искать, заменять или проверять строки по шаблону.

Пример базового шаблона: поиск цифр в строке.

import re
text = "Цена 250 рублей, скидка 10%"
pattern = r'\d+'
match = re.search(pattern, text)
if match:
    print(match.group())  # 250

любой символ python (любой символ в регулярных выражениях python)

250

Python re match (регулярное выражение re.match в python)

Здесь \d - сокращённый класс для любой цифры, + - квантификатор «одно или более вхождений». Без сырой строки пришлось бы писать '\\d+'.

Типичная ошибка: забыть сырую строку - тогда обратная косая черта воспринимается как экранирование в Python. Решение: всегда используйте r'' для regex.

Как задать любой символ с помощью точки (.)

Метасимвол . соответствует любому одиночному символу, кроме символа новой строки (\n).

import re
print(re.findall(r'т.ст', 'текст, тест, ткст'))

символы регулярных выражений python (символы регулярных выражений python)

['тест', 'ткст']

Шаблон т.ст найдёт слова, где между «т» и «ст» стоит один символ.

Проблема: точка не совпадает с переводом строки. Если нужно совпадение с любым символом, включая \n, используйте флаг re.DOTALL.

Как использовать квантификаторы для повторения символов

Квантификаторы управляют количеством повторений предыдущего элемента.

  • * - ноль или больше
  • + - один или больше
  • ? - ноль или один
  • {m,n} - от m до n включительно
import re
print(re.findall(r'\d{2,4}', '12 123 12345 1'))
['12', '123', '1234']

Шаблон \d{2,4} находит последовательности из 2–4 цифр.

Ошибка: пересечение совпадений - по умолчанию квантификаторы «жадные». Если нужно минимальное совпадение, добавьте ? после квантификатора (например, *?, +?).

Как задать набор символов с помощью квадратных скобок [ ]

Внутри скобок перечисляются допустимые символы или диапазоны (a-z, 0-9). Символ ^ в начале набора инвертирует его.

import re
print(re.findall(r'[аеёиоуыэюя]', 'Привет, как дела?'))
['и', 'е', 'а', 'е', 'а']

Шаблон ищет все гласные буквы русского алфавита.

Важно: большинство метасимволов внутри [...] теряют своё специальное значение (кроме \, ^, - и ]). Не экранируйте без необходимости.

Как использовать якоря начала и конца строки

^ - начало строки, $ - конец строки. Они не захватывают символы, а указывают позицию.

import re
print(bool(re.search(r'^Привет', 'Привет, мир!')))  # True
print(bool(re.search(r'мир!$', 'Привет, мир!')))    # True
True
True

С флагом re.MULTILINE ^ и $ совпадают с началом/концом каждой строки.

Ошибка: забыть, что ^ внутри [...] меняет смысл на отрицание.

Как создавать группы и обратные ссылки

Круглые скобки ( ) создают группу, которую можно извлечь или использовать в обратной ссылке (\1, \2 и т.д.).

import re
match = re.search(r'(\w+)@(\w+)\.(\w+)', 'user@example.com')
if match:
    print(match.group(1), match.group(2))  # user example
user example

Группы также можно именовать: (?P<name>...).

Проблема: нумерация групп начинается с 1, а group(0) возвращает всё совпадение. При использовании обратных ссылок в шаблоне требуется экранирование: \\1 в обычной строке или r'\1'.

Как экранировать специальные символы

Чтобы использовать метасимвол как обычный, перед ним ставится обратная косая черта: \., \*, \+.

import re
print(re.findall(r'\.', 'точка.ещё.точка'))
['.', '.']

Типичная ошибка: неверное количество обратных косых черт. В сырой строке r'\.' - одна косая для regex. В обычной строке пришлось бы писать '\\.'.

Как использовать сокращенные классы символов

Python предоставляет сокращения для популярных наборов:

  • \d - цифра (аналог [0-9])
  • \w - буква, цифра, подчёркивание (аналог [a-zA-Z0-9_] для латиницы)
  • \s - пробельный символ (пробел, табуляция, перевод строки)
  • \D, \W, \S - инверсия
import re
print(re.findall(r'\w+', 'Python 3.11 - мощный язык!'))
['Python', '3', '11', 'мощный', 'язык']

Примечание: \w не включает русские буквы по умолчанию; для их учёта используйте флаг re.ASCII (отключает юникод) или явные диапазоны [а-яА-ЯёЁ].

Как использовать флаги (re.IGNORECASE, re.MULTILINE и другие)

Флаги изменяют поведение regex. Передаются вторым аргументом в функции или в шаблоне через (?i).

import re
text = "Python\npython\nPYTHON"
print(re.findall(r'^python', text, re.IGNORECASE | re.MULTILINE))
['Python', 'python', 'PYTHON']

Без re.MULTILINE ^ совпал бы только в начале всей строки.

Ошибка: забыть комбинировать флаги через побитовое ИЛИ (|). Также флаг re.UNICODE включён по умолчанию; re.ASCII отключает его.

Расширенные примеры использования символов регулярных выражений

1. Lookahead и lookbehind (опережающая и ретроспективная проверка)

Эти конструкции не захватывают символы, а только проверяют условие.

  • (?=...) - положительный lookahead: совпадение, если после текущей позиции следует ...
  • (?!...) - отрицательный lookahead
  • (?<=...) - положительный lookbehind (только фиксированной длины)
  • (?<!...) - отрицательный lookbehind
Пример
import re
# Найти слово, после которого идёт '!' без восклицательного знака в результате
text = "Привет! Как дела? Пока!"
print(re.findall(r'\w+(?=!)', text))
['Привет', 'Пока']
Пример
# Найти слово, перед которым стоит 'Как '
print(re.findall(r'(?<=Как )\w+', text))
['дела?']

Особенность: lookbehind не поддерживает квантификаторы с неопределённой длиной (*, +).

2. Нежадные (ленивые) квантификаторы

По умолчанию квантификаторы жадные - захватывают максимально длинную строку. Добавление ? делает их ленивыми.

Пример
import re
html = "<div>текст</div><div>ещё</div>"
# Жадный:
print(re.findall(r'<div>.*</div>', html))
# Ленивый:
print(re.findall(r'<div>.*?</div>', html))
['<div>текст</div><div>ещё</div>']
['<div>текст</div>', '<div>ещё</div>']

3. Pattern с комментариями (re.VERBOSE)

Флаг re.VERBOSE (или re.X) позволяет писать шаблон в несколько строк, игнорируя пробелы и добавляя комментарии с #.

Пример
import re
pattern = re.compile(r'''
    \b            # граница слова
    \d{2,4}       # от 2 до 4 цифр
    \s?           # необязательный пробел
    [а-яА-Я]+     # хотя бы одна русская буква
    \b
''', re.VERBOSE | re.IGNORECASE)
print(pattern.findall('75 лет 1234 года 5 лет'))
['75 лет', '1234 года']

Пробелы в шаблоне игнорируются, поэтому количество лет «5» не совпало (одна цифра).

4. Использование границы слова \b

\b совпадает на стыке символа слова (\w) и не-слова. Полезно для поиска целых слов.

Пример
import re
print(re.findall(r'\bкот\b', 'кот, котёнок, котик'))
['кот']

Без \b нашлись бы все вхождения «кот», включая части других слов.

5. Атомарные группы и possessive квантификаторы

В Python нет встроенных атомарных групп, но можно эмулировать с помощью (?>...) - такая группа не отдаёт символы обратно при backtracking. Начиная с Python 3.11 поддерживается (?>...).

Пример
import re
# Пример без атомарной группы - backtracking приводит к совпадению
print(re.search(r'a(?:bc|b)c', 'abcc'))  # совпадёт 'abcc'
# С атомарной группой - после выбора bc группа не перебирает b
print(re.search(r'a(?>bc|b)c', 'abcc'))  # не совпадёт, потому что bc уже захвачено, c не хватает
<re.Match object; span=(0,4), match='abcc'>
None

Это предотвращает ненужный перебор вариантов и ускоряет поиск.

6. Условные шаблоны (if-then-else)

Конструкция (?(id/name)yes_pattern|no_pattern) позволяет сопоставлять разные шаблоны в зависимости от того, была ли найдена группа.

Пример
import re
# Если есть префикс 'tel:', то после него ищем номер из 10 цифр, иначе - произвольный номер
pattern = r'(tel:)?(?(1)\d{10}|\d{7})'
tests = ['tel:1234567890', '1234567', 'tel:12345']
for t in tests:
    m = re.search(pattern, t)
    print(t, '->', m.group() if m else None)
tel:1234567890 -> 1234567890
1234567 -> 1234567
tel:12345 -> None

7. Обработка Unicode с помощью \p{...} (Python 3.8+ модуль regex)

Стандартный модуль re не поддерживает \p{...}, но сторонний модуль regex даёт юникодные категории. Если он установлен:

Пример
import regex
print(regex.findall(r'\p{Lu}+', 'Привет Мир'))  # заглавные буквы
['П', 'М']

Для стандартного re можно использовать [\u0400-\u04FF].

8. Пересечение и исключение в символьных классах (модуль regex)

Модуль regex поддерживает операторы && (пересечение) и -- (вычитание).

Пример
import regex
# Все латинские буквы, кроме гласных
print(regex.findall(r'[a-z&&[^aeiou]]+', 'hello world'))
['hll', 'wrld']

Символы регулярных выражений Python - comments

En
символы регулярных выражений python (python)