Перейти к основному содержимому

Регулярные выражения — флаги и жадность

Разработчику

Предыдущий: проверки вокруг совпадения.
Следующий: рецепты и командная строка.


Флаги — как меняется поведение

Флаг (модификатор) подключается к шаблону и меняет правила. В JavaScript пишут после закрывающего /: /pattern/gim. В C# — свойства RegexOptions: IgnoreCase, Multiline.

ФлагJSСмысл для новичка
без учёта регистраiThe = the = THE
все совпаденияgне останавливаться на первом
многострочностьm^ и $ на каждой строке текста

В C# глобального g нет: один вызов Match — первое совпадение, Matches — все.

В Python re.findall ищет все; флаги задают через re.IGNORECASE и т.д.


Флаг i — регистр

Текст:

Error в логе и ERROR на сервере
ШаблонНайдёт
Errorтолько Error
Error + флаг iError и ERROR

Для кириллицы поведение зависит от движка и локали; надёжнее явный класс [Ее]rror или нормализация текста до поиска.


Флаг g — все вхождения

Текст:

cat sat on the mat
ШаблонПоведение
/at/первое at в cat
/at/gat в cat, at в mat

В редакторе «заменить все» обычно включает аналог глобального поиска.


Флаг m — несколько строк в одном тексте

Текст:

строка one
строка two

Шаблон ^строка без m — только если весь текст начинается со слова строка.

С флагом m ^ и $ привязаны к началу и концу каждой строки (между \n).

Пример: найти at в конце каждой строки:

/at$/gm

Подойдут окончания one / two, где есть at… В учебных фразах чаще срабатывает на cat, mat — смысл тот же: якорь к строке, а не ко всему файлу.


Жадность — главная ловушка новичка

По умолчанию квантификаторы жадные: берут максимум символов, который ещё позволяет остаток шаблона сойтись.

Текст:

<div>A</div> и <div>B</div>

Шаблон:

<div>.*</div>
ЭтапЧто происходит
<div>совпало с первым тегом
.*жадно тянет всё до последнего возможного
</div>подстраивается под последний </div>

Одно огромное совпадение: от первого <div> до последнего </div> — внутри и A, и B.


Ленивый квантификатор ? после *, +, {}

Добавьте ? после квантификатора — повторение станет ленивым (минимальным).

ЖадныйЛенивый
.*.*?
.+.+?
\d{2,5}\d{2,5}?

Тот же текст, шаблон:

<div>.*?</div>

Результат: два совпадения — <div>A</div> и <div>B</div>.

Потренируйтесь в лаборатории — пресет Жадный vs ленивый.


Когда что использовать

ЗадачаПодсказка
Вытащить первый блокленивый .*? или точнее — «всё кроме >»: <div>[^<]*</div>
До конца строки.* с якорем $
JSON/HTML с вложенностьюregex плохо справляется — парсер

Сводка

ПроблемаРешение
Нашёл только первоефлаг g или цикл Matches
The не находит THEфлаг i
^ не работает во 2-й строке файлафлаг m
.* съело полстраницы.*? или уточнить класс символов

Дальше: Рецепты и командная строка →

См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).