Флаги: IGNORECASE, MULTILINE, DOTALL

Учимся менять поведение всего паттерна одним переключателем-флагом.

Флаг — модификатор, который меняет правила сопоставления для всего паттерна: например, отключает чувствительность к регистру.

Зачем нужны флаги

Иногда стандартное поведение неудобно. Регулярки чувствительны к регистру: cat не найдёт Cat. Якорь ^ по умолчанию означает начало всей строки, а не каждой строки в многострочном тексте. Точка не ловит перевод строки. Всё это переключается флагами — третьим аргументом функций re.

re.IGNORECASE — без учёта регистра

Флаг re.IGNORECASE (коротко re.I) делает поиск регистронезависимым:

import re

text = "Cat CAT cat CaT"
print(re.findall(r"cat", text))
print(re.findall(r"cat", text, re.IGNORECASE))

Вывод:

['cat']
['Cat', 'CAT', 'cat', 'CaT']

Без флага нашлось одно точное совпадение; с флагом — все четыре написания. Это незаменимо, когда регистр неважен: ключевые слова, email, расширения файлов.

re.MULTILINE — якоря на каждой строке

Якоря ^ (начало) и $ (конец) по умолчанию относятся ко всей строке-тексту целиком. Флаг re.MULTILINE (re.M) заставляет их срабатывать на каждой строке многострочного текста:

import re

text = "one\ntwo\nthree"
print(re.findall(r"^\w+", text))
print(re.findall(r"^\w+", text, re.MULTILINE))

Вывод:

['one']
['one', 'two', 'three']

Без флага ^\w+ поймал только первое слово (начало всего текста). С re.MULTILINE — слово в начале каждой строки.

re.DOTALL — точка ловит перевод строки

Как мы помним, точка не совпадает с символом перевода строки \n. Флаг re.DOTALL (re.S) снимает это ограничение — теперь точка значит «вообще любой символ, включая перенос»:

import re

text = "начало\nконец"
print(re.search(r"начало.конец", text))
print(re.search(r"начало.конец", text, re.DOTALL).group())

Вывод:

None
начало
конец

Без флага точка не перешагнула через \n и совпадения не было. С re.DOTALL точка поймала и перевод строки — поэтому шаблон совпал, и в выводе текст занял две строки.

Несколько флагов сразу

Флаги комбинируют оператором |: re.IGNORECASE | re.MULTILINE. А ещё их можно включать прямо внутри паттерна префиксом, например (?i) для регистронезависимости:

import re

print(re.findall(r"(?i)cat", "Cat CAT cat"))

Вывод:

['Cat', 'CAT', 'cat']

Итог

  • re.IGNORECASE — поиск без учёта регистра.
  • re.MULTILINE^ и $ срабатывают на каждой строке.
  • re.DOTALL — точка начинает ловить и перевод строки.
  • Флаги передают третьим аргументом и комбинируют через |; есть и встроенные префиксы вроде (?i).
Проверьте себя
1. Что делает флаг re.IGNORECASE?
AИгнорирует пробелы в паттерне
BДелает поиск нечувствительным к регистру букв
CУскоряет поиск
DЗаставляет точку ловить перевод строки
2. Зачем нужен флаг re.MULTILINE?
AЧтобы паттерн занимал несколько строк в коде
BЧтобы якоря ^ и $ срабатывали на каждой строке текста, а не только в начале/конце всего текста
CЧтобы искать сразу в нескольких файлах
DЧтобы точка ловила перенос строки
3. Какой флаг заставит точку . совпадать в том числе с переводом строки \n?
Are.IGNORECASE
Bre.MULTILINE
Cre.DOTALL
Dre.VERBOSE
Поддержать проект