Предопределённые и пользовательские классы символов, инверсия
Классы символов позволяют указать набор допустимых символов для одной позиции в шаблоне. Это мощный инструмент для гибкого поиска.
Класс символов задаётся в квадратных скобках [] и соответствует одному любому символу из набора:
import re
# Любая гласная
re.search(r'[aeiou]', 'hello') # 'e'
# Любая цифра
re.search(r'[0123456789]', 'abc5def') # '5'
# Любая буква из набора
re.search(r'[abc]', 'dog') # None
re.search(r'[abc]', 'cat') # 'a'Для указания диапазона используйте дефис -:
# Любая строчная буква
re.search(r'[a-z]', 'Hello') # 'e'
# Любая заглавная буква
re.search(r'[A-Z]', 'Hello') # 'H'
# Любая цифра
re.search(r'[0-9]', 'abc123') # '1'
# Комбинированные диапазоны
re.search(r'[a-zA-Z]', '123') # None
re.search(r'[a-zA-Z]', 'abc') # 'a'# Буквы и цифры
re.search(r'[a-zA-Z0-9]', 'test_123') # 't'
# Гласные и цифры
re.search(r'[aeiou0-9]', 'hello123') # 'e'^ в начале класса означает отрицание — любой символ, КРОМЕ указанных:
# Любая цифра
re.search(r'[0-9]', 'abc5def') # '5'
# Любой символ, кроме цифры
re.search(r'[^0-9]', 'abc5def') # 'a'
# Любая буква, кроме гласных (согласные)
re.search(r'[^aeiouAEIOU]', 'hello') # 'h'Важно:
^работает как инверсия только внутри[]и только в начале. В других позициях это literal^.
re.search(r'[a-z^]', 'a^b') # '^' — здесь ^ это literal
re.search(r'^[a-z]', 'abc') # 'a' — здесь ^ это якорь началаPython предоставляет готовые классы через escape-последовательности:
| Класс | Значение | Эквивалент |
|---|---|---|
\d | Цифра | [0-9] |
\D | Не цифра | [^0-9] |
\w | Word-символ | [a-zA-Z0-9_] |
\W | Не word-символ | [^a-zA-Z0-9_] |
\s | Пробельный символ | [ \t\n\r\f\v] |
\S | Не пробельный символ | [^ \t\n\r\f\v] |
re.search(r'\d', 'abc123') # '1'
re.search(r'\d+', 'abc123') # '123' — одна или более цифр
re.search(r'\D', '123abc') # 'a'
re.search(r'\D+', '123abc') # 'abc're.search(r'\w', 'hello_world') # 'h'
re.search(r'\w+', 'hello world') # 'hello'
re.search(r'\W', 'hello world') # ' ' (пробел)
re.search(r'\W+', 'hello world') # ' ' (пробелы)Важно:
\wвключает подчёркивание_, но не включает дефис-, точку.и другие спецсимволы.
re.search(r'\s', 'hello world') # ' ' (пробел)
re.search(r'\s+', 'hello world') # ' ' (несколько пробелов)
re.search(r'\s', 'hello\tworld') # '\t' (табуляция)
re.search(r'\s', 'hello\nworld') # '\n' (newline)
re.search(r'\S', ' abc') # 'a' (первый непробельный)# Идентификатор: буква или подчёркивание, затем буквы/цифры/подчёркивания
pattern = r'^[a-zA-Z_]\w*$'
re.match(pattern, 'variable') # Match
re.match(pattern, '_private') # Match
re.match(pattern, 'var123') # Match
re.match(pattern, '123var') # None — начинается с цифры
re.match(pattern, 'my-var') # None — дефис не входит в \wtext = 'Цена: 1234 руб., скидка 5%'
# Все числа
re.findall(r'\d+', text) # ['1234', '5']
# Числа с пробелами как разделителями тысяч
text = 'Цена: 1 234 567 руб.'
re.findall(r'[\d ]+', text) # ['1 234 567']text = 'Hello, world! Это тест.'
# Только латинские слова
re.findall(r'[a-zA-Z]+', text) # ['Hello', 'world']
# Слова с подчёркиванием
re.findall(r'\w+', text) # ['Hello', 'world', 'Это', 'тест']# HEX-цвет: # и 6 hex-символов
pattern = r'^#[0-9a-fA-F]{6}$'
re.match(pattern, '#FF5733') # Match
re.match(pattern, '#ff5733') # Match
re.match(pattern, '#GGGGGG') # None — G не hex-символ
re.match(pattern, 'FF5733') # None — нет #Некоторые символы внутри [] теряют специальное значение:
# Точка внутри [] — literal точка
re.search(r'[.]', 'abc.def') # '.'
re.search(r'[.]', 'abcdef') # None
# Звёздочка внутри [] — literal звёздочка
re.search(r'[*]', 'a*b') # '*'
# Плюс внутри [] — literal плюс
re.search(r'[+]', 'a+b') # '+'# ] требует экранирования
re.search(r'[\]]', 'a]b') # ']'
re.search(r'[\[\]]', 'a[b') # '['
re.search(r'[\[\]]', 'a]b') # ']'
# ^ в начале — инверсия, в другом месте — literal
re.search(r'[a^b]', 'a^b') # '^'
re.search(r'[a^b]', 'abc') # 'a'
# - в начале или конце — literal, в середине — диапазон
re.search(r'[-abc]', '-abc') # '-'
re.search(r'[abc-]', 'abc-') # '-'
re.search(r'[a-z]', 'm') # 'm' — диапазонВ Python 3 \w, \d, \s по умолчанию работают с Unicode:
# Кириллица входит в \w
re.search(r'\w+', 'Привет мир') # 'Привет'
# Но \w несоответствует пробел
re.search(r'\w+', 'Привет мир') # 'Привет', не 'Привет мир'
# Для всех букв используйте Unicode-категории
re.search(r'[\w\s]+', 'Привет мир') # 'Привет мир'Для ограничения \w, \d, \s только ASCII-символами:
# По умолчанию (Unicode):
re.search(r'\w+', 'Привет') # 'Привет'
# Только ASCII:
re.search(r'\w+', 'Привет', re.ASCII) # None
re.search(r'\w+', 'Hello', re.ASCII) # 'Hello'# Ошибка: ищет literal символы [0-9]
re.search(r'[0-9]', 'abc5') # '5' — правильно
# Ошибка: без скобок ищет '0', '-', '9' по отдельности
re.search(r'0-9', '0-9') # '0-9' — это не класс!# Ошибка: думают, что [^a-z]соответствует заглавные буквы
re.search(r'[^a-z]', 'ABC') # 'A' — правильно, но...
re.search(r'[^a-z]', '123') # '1' — цифры тоже!
# Для только заглавных используйте [A-Z]
re.search(r'[A-Z]', 'ABC') # 'A'# Ошибка: дефис в середине воспринимается как диапазон
re.search(r'[a-z-]', 'abc-') # '-' — правильно
re.search(r'[a--z]', 'abc') # Ошибка: диапазон a- до z
# Правильно: дефис в начале или конце
re.search(r'[-a-z]', '-abc') # '-'
re.search(r'[a-z-]', 'abc-') # '-'[] соответствует одному любому символу из набора[a-z], [0-9]^ в начале класса инвертирует: [^0-9] — всё, кроме цифр\d (цифры), \w (word), \s (пробелы)\D, \W, \S[] большинство метасимволов теряют специальное значение], \, ^ (в начале), - (в середине) требуют вниманияВопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.