IGNORECASE, MULTILINE, DOTALL, VERBOSE, ASCII, LOCALE
Флаги изменяют поведение регулярных выражений: регистронезависимость, многострочный режим, работа с Unicode и другие.
Флаги передаются как второй аргумент функциям re или при компиляции:
import re
# Второй аргумент
re.search(r'pattern', 'string', re.IGNORECASE)
# При компиляции
pattern = re.compile(r'pattern', re.IGNORECASE | re.MULTILINE)
# Комбинирование через |
re.search(r'pattern', 'string', re.IGNORECASE | re.MULTILINE | re.DOTALL)Делает поиск регистронезависимым:
# Без флага
re.search(r'hello', 'Hello') # None
re.search(r'HELLO', 'Hello') # None
# С флагом
re.search(r'hello', 'Hello', re.IGNORECASE) # 'Hello'
re.search(r'HELLO', 'Hello', re.IGNORECASE) # 'Hello'
re.search(r'HeLLo', 'Hello', re.IGNORECASE) # 'Hello'# Классы тоже становятся регистронезависимыми
re.search(r'[a-z]+', 'ABC', re.IGNORECASE) # 'ABC'
# Unicode буквы
re.search(r'[а-я]+', 'ПРИВЕТ', re.IGNORECASE) # 'ПРИВЕТ'Изменяет поведение ^ и $:
text = """first line
second line
third line"""
# Без MULTILINE
re.findall(r'^second', text) # [] — ^соответствует только начало всей строки
re.findall(r'second$', text) # [] — $соответствует только конец всей строки
# С MULTILINE
re.findall(r'^second', text, re.MULTILINE) # ['second'] — начало строки
re.findall(r'line$', text, re.MULTILINE) # ['line', 'line', 'line'] — конец каждой строкиlog_text = """2024-03-09 ERROR Database error
2024-03-09 INFO Server started
2024-03-09 WARNING High memory"""
# Найти все ERROR строки
re.findall(r'^.*ERROR.*$', log_text, re.MULTILINE)
# ['2024-03-09 ERROR Database error']Заставляет точку .соответствует символы новой строки:
text = "Hello\nWorld"
# Без DOTALL
re.search(r'Hello.*World', text) # None — . несоответствует \n
re.search(r'Hello.*World', text, re.DOTALL) # 'Hello\nWorld'
# Практический пример: HTML между тегами
html = "<div>\n content\n</div>"
re.search(r'<div>.*</div>', html) # None
re.search(r'<div>.*</div>', html, re.DOTALL) # '<div>\n content\n</div>'Позволяет форматировать паттерн для читаемости:
# Без VERBOSE
pattern = r'\d{4}-\d{2}-\d{2}'
# С VERBOSE — можно добавлять пробелы и комментарии
pattern = r'''
\d{4} # год
- # разделитель
\d{2} # месяц
- # разделитель
\d{2} # день
'''
re.compile(pattern, re.VERBOSE)В режиме VERBOSE пробелы игнорируются (кроме внутри классов и экранированных):
# Пробелы игнорируются
pattern = r'''
\d+ \s+ \d+
'''
# Эквивалентно: r'\d+\s+\d+'
# Пробел внутри класса сохраняется
pattern = r'[a-z ]+' #соответствует буквы и пробел
# Экранированный пробел сохраняется
pattern = r'\d+\ \d+' #соответствует '123 456'email_pattern = re.compile(r'''
^ # начало строки
[\w.-]+ # имя пользователя
@ # @
[\w.-]+ # домен
\. # точка
[a-zA-Z]{2,} # TLD
$ # конец строки
''', re.VERBOSE)
bool(email_pattern.match('user@example.com')) # TrueОграничивает \w, \d, \s только ASCII-символами:
# По умолчанию (Unicode)
re.search(r'\w+', 'Привет') # 'Привет' — кириллица входит в \w
# С ASCII
re.search(r'\w+', 'Привет', re.ASCII) # None — кириллица не входит
re.search(r'\w+', 'Hello', re.ASCII) # 'Hello'# Unicode режим
re.search(r'[a-z]+', 'Привет') # None — кириллица не в диапазоне a-z
# ASCII режим (не влияет на явные классы)
re.search(r'[a-z]+', 'abc', re.ASCII) # 'abc'Использует настройки локали для \w, \d, \s, \b. Устарел, рекомендуется Unicode.
# Устаревший подход
re.search(r'\w+', 'текст', re.LOCALE)
# Современный подход (по умолчанию)
re.search(r'\w+', 'текст') # 'текст'Используйте | для комбинирования:
# Игнорирование регистра + многострочность
pattern = re.compile(r'^hello', re.IGNORECASE | re.MULTILINE)
text = """Hello World
hello universe
HELLO everyone"""
pattern.findall(text) # ['Hello', 'hello', 'HELLO']pattern = re.compile(r'''
^ # начало строки
.* # любой текст (включая newline)
hello # слово hello
.* # любой текст
$ # конец строки
''', re.IGNORECASE | re.MULTILINE | re.DOTALL | re.VERBOSE)Флаги можно задавать внутри паттерна:
# (?i) — IGNORECASE
re.search(r'(?i)hello', 'HELLO') # 'HELLO'
# (?m) — MULTILINE
re.search(r'(?m)^hello', 'hello\nworld') # 'hello'
# (?s) — DOTALL
re.search(r'(?s)hello.*world', 'hello\nworld') # 'hello\nworld'
# (?x) — VERBOSE
re.search(r'(?x) h e l l o', 'hello') # 'hello'# Флаг только для части паттерна
re.search(r'(?i:hello) world', 'HELLO world') # 'HELLO world'
re.search(r'(?i:hello) world', 'hello WORLD') # None — флаг только для 'hello'
# Отключение флага
re.search(r'(?i)hello(?-i) WORLD', 'HELLO world') # None
re.search(r'(?i)hello(?-i) WORLD', 'HELLO WORLD') # 'HELLO WORLD'text = """
Name: John
Age: 30
City: Moscow
Name: Jane
Age: 25
City: Paris
"""
# Извлечение имён
names = re.findall(r'^Name: (.+)$', text, re.MULTILINE)
# ['John', 'Jane']# Минимум 8 символов, буква, цифра, спецсимвол
pattern = re.compile(r'''
^ # начало
(?=.*[A-Za-z]) # есть буква
(?=.*\d) # есть цифра
(?=.*[@$!%*?&]) # есть спецсимвол
[A-Za-z\d@$!%*?&]{8,} # только допустимые символы, минимум 8
$ # конец
''', re.VERBOSE)
bool(pattern.match('Pass123!')) # True
bool(pattern.match('password')) # Falsehtml = "<div>\n HELLO\n</div>"
# Найти текст между тегами, игнорируя регистр и newline
match = re.search(r'<div>(.*?)</div>', html, re.IGNORECASE | re.DOTALL)
match.group(1) # '\n HELLO\n'text = "Hello\nWorld"
# Ошибка: . несоответствует newline
re.search(r'Hello.*World', text) # None
# Правильно: с DOTALL
re.search(r'Hello.*World', text, re.DOTALL) # 'Hello\nWorld'text = "line1\nline2\nline3"
# Ошибка: MULTILINE без ^ или $ не имеет эффекта
re.findall(r'line', text, re.MULTILINE) # ['line', 'line', 'line'] — то же, что без MULTILINE
# Правильно: с якорями
re.findall(r'^line', text, re.MULTILINE) # ['line', 'line', 'line']# Ошибка: пробелы игнорируются
pattern = r'hello world' #соответствует 'helloworld', а не 'hello world'
# Правильно: экранировать пробелы
pattern = r'hello\ world' #соответствует 'hello world'
# Или использовать класс
pattern = r'hello[ ]world' #соответствует 'hello world're.IGNORECASE (re.I, (?i)) — игнорирование регистраre.MULTILINE (re.M, (?m)) — ^ и $ для каждой строкиre.DOTALL (re.S, (?s)) — точкасоответствует newlinere.VERBOSE (re.X, (?x)) — пробелы и комментарии в паттернеre.ASCII (re.A, (?a)) — ограничить \w, \d, \s ASCII|(?i), (?m) можно применять локальноre.VERBOSE для сложных паттернов с комментариямиВопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.