<p align="center"> <br/> <a href="https://github.com/ziishaned/learn-regex"> <img src="https://i.imgur.com/bYwl7Vf.png" alt="Learn Regex"> </a> <br /><br /> <p> <a href="https://twitter.com/ziishaned"> <img src="https://img.shields.io/twitter/follow/ziishaned.svg?style=social" /> </a> <a href="https://github.com/ziishaned"> <img src="https://img.shields.io/github/followers/ziishaned.svg?label=Follow%20%40ziishaned&style=social" /> </a> </p> </p> ## Translations: * [English](../README.md) * [Español](../translations/README-es.md) * [Français](../translations/README-fr.md) * [Português do Brasil](../translations/README-pt_BR.md) * [中文版](../translations/README-cn.md) * [日本語](../translations/README-ja.md) * [한국어](../translations/README-ko.md) * [Turkish](../translations/README-tr.md) * [Greek](../translations/README-gr.md) * [Magyar](../translations/README-hu.md) * [Polish](../translations/README-pl.md) * [Русский](../translations/README-ru.md) * [Tiếng Việt](../translations/README-vn.md) * [فارسی](../translations/README-fa.md) * [עברית](translations/README-he.md) ## Что такое Регулярное выражение? [](https://gum.co/learn-regex) > Регулярное выражение - это группа букв или символов, которая используется для поиска определенного шаблона в тексте. Регулярное выражение - это шаблон, сопоставляемый с искомой строкой слева направо. Термин «Регулярное выражение» сложно произносить каждый раз, поэтому, обычно, вы будете сталкиваться с сокращениями "регэкспы" или "регулярки". Регулярные выражения используются для замен текста внутри строк, валидации форм, извлечений подстрок по определенным шаблонам и множества других вещей. Представьте, что вы пишете приложение и хотите установить правила, по которым пользователь выбирает свой юзернейм. Мы хотим, чтобы имя пользователя содержало буквы, цифры, подчеркивания и дефисы. Мы также хотим ограничить количество символов в имени пользователя, чтобы оно не выглядело безобразно. Для этого, используем следующее регулярное выражение: <br/><br/> <p align="center"> <img src="../img/regexp-ru.png" alt="Regular expression"> </p> Регулярное выражения выше может принимать строки `john_doe`,`jo-hn_doe` и `john12_as`. Оно не валидирует `Jo`, поскольку эта строка содержит заглавные буквы, а также она слишком короткая. ## Содержание - [Совпадения](#1-совпадения) - [Метасимволы](#2-метасимволы) - [Точка](#21-точка) - [Набор символов](#22-набор-символов) - [Отрицание набора символов](#221-отрицание-набора-символов) - [Повторения](#23-повторения) - [Звёздочка](#231-звёздочка) - [Плюс](#232-плюс) - [Знак вопроса](#233-знак-вопроса) - [Фигурные скобки](#24-фигурные-скобки) - [Скобочные группы](#25-скобочные-группы) - [Альтернация](#26-альтернация) - [Экранирование](#27-экранирование) - [Якоря](#28-якоря) - [Каретка](#281-каретка) - [Доллар](#282-доллар) - [Наборы сокращений и диапазоны](#3-наборы-сокращений-и-диапазоны) - [Опережающие и ретроспективные проверки](#4-опережающие-и-ретроспективные-проверки) - [Положительное опережающее условие](#41-положительное-опережающее-условие) - [Отрицательное опережающее условие](#42-отрицательное-опережающее-условие) - [Положительное ретроспективное условие](#43-положительное-ретроспективное-условие) - [Отрицательное ретроспективное условие](#44-отрицательное-ретроспективное-условие) - [Флаги](#5-флаги) - [Поиск без учета регистра](#51-поиск-без-учета-регистра) - [Глобальный поиск](#52-глобальный-поиск) - [Мультистроковый поиск](#53-мультистроковый-поиск) - [Жадные vs ленивые квантификаторы](#6-жадные-vs-ленивые-квантификаторы) ## 1. Совпадения. В сущности, регулярное выражение - это просто набор символов, который мы используем для поиска в тексте. Например, регулярное выражение `the` состоит из буквы `t`, за которой следует буква `h`, за которой следует буква `e`. <pre> "the" => The fat cat sat on <a href="#learn-regex"><strong>the</strong></a> mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/dmRygT/1) Регулярное выражение `123` соответствует строке `123`. Регулярное выражение сопоставляется с входной строкой, сравнивая каждый символ в регулярном выражении с каждым символом во входной строке по одному символу за другим. Регулярные выражения обычно чувствительны к регистру, поэтому регулярное выражение `The` не будет соответствовать строке `the`. <pre> "The" => <a href="#learn-regex"><strong>The</strong></a> fat cat sat on the mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/1paXsy/1) ## 2. Метасимволы Метасимволы это блоки, из которых строятся регулярные выражения. Метасимволы не означают что-то сами по себе, вместо этого они интерпретируются для распознавания специальных групп символов. Некоторые метасимволы имеют особые обозначения и пишутся в квадратных скобках. Существуют следующие метасимволы: |Метасимволы|Описание| |:----:|----| |.|Точка соответствует любому отдельному символу, кроме разрыва строки.| |[ ]|Класс символов. Находить любые символы заключенные в квадратных скобках.| |[^ ]|Отрицание класа символов. Находить любые символы не заключенные в квадратных скобках.| |*|Находить 0 или более повторений предыдущего символа.| |+|Находить 1 или более повторений предыдущего символа.| |?|Сделать предыдущий символ необязательным.| |{n,m}|Скобки. Находить по крайней мере "n" но не более чем "m" повторений предыдущего символа.| |(xyz)|Группа символов. Находить только символы xyz в указанном порядке.| |||Чередование. Находить либо буквы до, либо буквы после символа.| |\|Экранирование. Позволяет находить зарезервированные символы: <code>[ ] ( ) { } . * + ? ^ $ \ |</code>| |^|Обозначает начало пользовательского ввода.| |$|Обозначает конец пользовательского ввода.| ## 2.1 Точка Точка `.` это простейший пример метасимвола. Метасимвол `.` находит любой отдельный символ. Точка не будет находить символы перехода или перевода строки. Например, регулярное выражение `.ar` обозначает: любой символ, за которым следуют буквы `a` и `r`. <pre> ".ar" => The <a href="#learn-regex"><strong>car</strong></a> <a href="#learn-regex"><strong>par</strong></a>ked in the <a href="#learn-regex"><strong>gar</strong></a>age. </pre> [Запустить регулярное выражение](https://regex101.com/r/xc9GkU/1) ## 2.2 Набор символов. Набор символов также называется классом символов. Квадратные скобки используются для определения набора символов. Дефис используется для указания диапазона символов. Порядок следования символов, заданный в квадратных скобках, не важен. Например, регулярное выражение `[Tt]he` обозначает заглавную `T` или строчную `t`, за которой следуют буквы `h` и `e`. <pre> "[Tt]he" => <a href="#learn-regex"><strong>The</strong></a> car parked in <a href="#learn-regex"><strong>the</strong></a> garage. </pre> [Запустить регулярное выражение](https://regex101.com/r/2ITLQ4/1) Точка внутри набора символов, однако, обозначает непосредственно точку, как символ. Регулярное выражение `ar[.]` обозначает строчную `a`, за которой следует `r`, за которой следует `.` (символ точки). <pre> "ar[.]" => A garage is a good place to park a c<a href="#learn-regex"><strong>ar.</strong></a> </pre> [Запустить регулярное выражение](https://regex101.com/r/wL3xtE/1) ### 2.2.1 Отрицание набора символов Знак вставки `^` обозначает начало строки, однако, когда вы вписываете его после открытия квадратных скобок, он отрицает набор символов. Например, регулярное выражение `[^c]ar` обозначает любой символ, кроме `c`, за которым следуют буквы `a` и `r`. <pre> "[^c]ar" => The car <a href="#learn-regex"><strong>par</strong></a>ked in the <a href="#learn-regex"><strong>gar</strong></a>age. </pre> [Запустить регулярное выражение](https://regex101.com/r/nNNlq3/1) ## 2.3 Повторения Символы `+`, `*` или `?` используются для обозначения того сколько раз появляется какой-либо подшаблон. Данные метасимволы могут вести себя по-разному, в зависимости от ситуации. ### 2.3.1 Звёздочка Символ `*` обозначает ноль или более повторений предыдущего совпадения. Регулярное выражение `a*` означает ноль или более повторений предыдущего строчного символа `a`. Если же символ появляется после набора или класса символов, он находит повторения всего набора символов. Например, регулярное выражение `[a-z]*` означает любое количество строчных букв в строке. <pre> "[a-z]*" => T<a href="#learn-regex"><strong>he</strong></a> <a href="#learn-regex"><strong>car</strong></a> <a href="#learn-regex"><strong>parked</strong></a> <a href="#learn-regex"><strong>in</strong></a> <a href="#learn-regex"><strong>the</strong></a> <a href="#learn-regex"><strong>garage</strong></a> #21. </pre> [Запустить регулярное выражение](https://regex101.com/r/7m8me5/1) Символы можно комбинировать, так, например, символ `*` может использоваться с метасимволом `.` для поиска одной строки с произвольным содержанием `.*`. Символ `*` может использоваться с символом пробела `\s`, чтобы находить строки с символами пробела. Например, выражение `\s*cat\s*` означает: ноль или более пробелов, за которыми следует слово `cat`, за которым следует ноль или более символов пробела. <pre> "\s*cat\s*" => The fat<a href="#learn-regex"><strong> cat </strong></a>sat on the con<a href="#learn-regex"><strong>cat</strong></a>enation. </pre> [Запустить регулярное выражение](https://regex101.com/r/gGrwuz/1) ### 2.3.2 Плюс Символ `+` соответствует одному или более повторению предыдущего символа. Например, регулярное выражение `c.+t` означает строчную `c`, за которой следует по крайней мере один символ, следом за которым идёт символ `t`. Стоит уточнить, что в данном шаблоне, `t` является последним `t` в предложении. <pre> "c.+t" => The fat <a href="#learn-regex"><strong>cat sat on the mat</strong></a>. </pre> [Запустить регулярное выражение](https://regex101.com/r/Dzf9Aa/1) ### 2.3.3 Знак вопроса В регулярном выражении метасимвол `?` делает предыдущий символ необязательным. Этот символ соответствует нулю или одному экземпляру предыдущего символа. Например, регулярное выражение `[T]?he` означает необязательную заглавную букву `T`, за которой следуют символы `h` и `e`. <pre> "[T]he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in the garage. </pre> [Запустить регулярное выражение](https://regex101.com/r/cIg9zm/1) <pre> "[T]?he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in t<a href="#learn-regex"><strong>he</strong></a> garage. </pre> [Запустить регулярное выражение](https://regex101.com/r/kPpO2x/1) ## 2.4 Фигурные скобки В фигурных скобках, которые также называются квантификаторами, указывается, сколько раз символ или группа символов могут повторяться. Например, регулярное выражение `[0-9]{2,3}` означает совпадение не менее 2 но не более 3 цифр в диапазоне от 0 до 9. <pre> "[0-9]{2,3}" => The number was 9.<a href="#learn-regex"><strong>999</strong></a>7 but we rounded it off to <a href="#learn-regex"><strong>10</strong></a>.0. </pre> [Запустить регулярное выражение](https://regex101.com/r/juM86s/1) Уберём второй номер (цифру 3), тогда, регулярное выражение `[0-9]{2,}` будет означать совпадение 2 или более цифр. Если мы также удалим запятую, то регулярное выражение `[0-9]{3}` будет означать совпадение точно с 3 цифрами. <pre> "[0-9]{2,}" => The number was 9.<a href="#learn-regex"><strong>9997</strong></a> but we rounded it off to <a href="#learn-regex"><strong>10</strong></a>.0. </pre> [Запустить регулярное выражение](https://regex101.com/r/Gdy4w5/1) <pre> "[0-9]{3}" => The number was 9.<a href="#learn-regex"><strong>999</strong></a>7 but we rounded it off to 10.0. </pre> [Запустить регулярное выражение](https://regex101.com/r/Sivu30/1) ## 2.5 Скобочные группы Скобочные группы это группы подшаблонов, которые написаны в круглых скобках `(...)`. Как мы уже говорили ранее в регулярном выражении, если мы поставим квантификатор после символа, он будет повторять предыдущий символ. Но если мы поставим квантификатор после скобочной группы, он будет искать всю группу. Например, регулярное выражение `(ab)*` соответствует нулю или более повторений символа "ab". Мы также можем использовать метасимвол чередования `|` внутри скобочной группы. Например, регулярное выражение `(c|g|p)ar` означает поиск одной из строчных букв `c`, `g` или `p`, за которыми следуют буквы `a` и `r`. <pre> "(c|g|p)ar" => The <a href="#learn-regex"><strong>car</strong></a> is <a href="#learn-regex"><strong>par</strong></a>ked in the <a href="#learn-regex"><strong>gar</strong></a>age. </pre> [Запустить регулярное выражение](https://regex101.com/r/tUxrBG/1) Обратите внимание, что скобочные группы не только находят, но и захватывают символы для использования на родительском языке. Родительским языком может быть python, javascript или практически любой язык, который реализует использование регулярных выражений как параметров функций. ### 2.5.1 Не запоминающие скобочные группы Бывает так, что группу определить нужно, а вот запоминать их содержимое в массиве не требуется. Подобный трюк осуществляется при помощи зарезервированной комбинации `?:` в круглых скобках `(...)`. Например, регулярное выражение `(?:c|g|p)ar` будет находить такие же шаблоны как и `(c|g|p)ar`, однако скобочная группа при этом создана не будет. <pre> "(?:c|g|p)ar" => The <a href="#learn-regex"><strong>car</strong></a> is <a href="#learn-regex"><strong>par</strong></a>ked in the <a href="#learn-regex"><strong>gar</strong></a>age. </pre> [Запустить регулярное выражение](https://regex101.com/r/Rm7Me8/1) Незапоминающиеся группы могут пригодиться, когда они используются в функциях поиска и замены, или в сочетании со скобочными группами, например, для предпросмотра при создании скобочной группы или другого вида выходных данных, смотрите также [4. Опережающие и ретроспективные проверки](#4-опережающие-и-ретроспективные-проверки). ## 2.6 Альтернация В регулярных выражениях, вертикальная черта `|` используется для определения альтернации (чередования). Альтернация по своей сути похожа на оператор ИЛИ между логическими выражениями. Может создаться впечатление, что чередование это то же самое, что и определение набора символов. Однако, большая разница между ними в том, что набор символов работает на уровне конкретных символов, в то время как альтернация работает на уровне выражений. Например, регулярное выражение `(T|t)he|car` объединяет два шаблона (заглавная `T` ИЛИ строчная `t`, с продолжением из `h` и `e`) и шаблон (строчная `c`, затем строчная `a`, за которой следует строчная `r`). Таким образом, в поиске будет участвовать любой из данных шаблонов, по аналогии с логической операцией ИЛИ в программировании и алгебре выражений. <pre> "(T|t)he|car" => <a href="#learn-regex"><strong>The</strong></a> <a href="#learn-regex"><strong>car</strong></a> is parked in <a href="#learn-regex"><strong>the</strong></a> garage. </pre> [Запустить регулярное выражение](https://regex101.com/r/fBXyX0/1) ## 2.7 Экранирование спецсимволов Обратный слэш `\` используется в регулярных выражениях для экранирования следующего символа. Это позволяет формировать шаблоны с поиском зарезервированных символов, таких как `{ } [ ] / \ + * . $ ^ | ?`. Для использования спецсимвола в шаблоне необходимо указать символ `\` перед ним. Как упомянуто выше, символ `.` является зарезервированным и соответствует любому значению, кроме символа новой строки. Бывают ситуации, когда необходимо найти точку в предложении, для таких случаев применимо экранирование. Рассмотрим выражение `(f|c|m)at\.?`, что соответствует следующему шаблону: строчный символ `f`, `c` или `m`, за которым следует строчные буквы `a` и `t`, с опциональной `.` точкой в конце. <pre> "(f|c|m)at\.?" => The <a href="#learn-regex"><strong>fat</strong></a> <a href="#learn-regex"><strong>cat</strong></a> sat on the <a href="#learn-regex"><strong>mat.</strong></a> </pre> [Запустить регулярное выражение](https://regex101.com/r/DOc5Nu/1) ## 2.8 Якоря Понятие якорей в регулярных выражениях используется для обозначения проверок, является ли соответствующий символ начальным или конечным символом входной строки. Якоря бывают двух типов: Первый тип - Каретка `^`, проверяет, является ли соответствующий символ начальным символом в тексте. Второй тип - Доллар `$`, проверяет, является ли соответствующий символ последним символом входной строки. ### 2.8.1 Каретка Символ каретки `^` используется для проверки, является ли соответствующий символ первым символом входной строки. Если мы применяем следующее регулярное выражение `^a` (если a является начальным символом) для строки `abc`, совпадение будет соответствовать букве `a`. Если же мы используем регулярное выражение `^b` на той же строке, мы не получим совпадения, поскольку во входящей строке `abc` "b" не является первым символом. Рассмотрим другое регулярное выражение: `^(T|t)he`, обозначающее заглавную `T` или строчную `t` как первый символ, за которым следуют символы букв `h` и `e`. Cоответственно: <pre> "(T|t)he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in <a href="#learn-regex"><strong>the</strong></a> garage. </pre> [Запустить регулярное выражение](https://regex101.com/r/5ljjgB/1) <pre> "^(T|t)he" => <a href="#learn-regex"><strong>The</strong></a> car is parked in the garage. </pre> [Запустить регулярное выражение](https://regex101.com/r/jXrKne/1) ### 2.8.2 Доллар Символ доллара `$` используется для проверки, является ли соответствующий символ последним символом входной строки. Например, регулярное выражение `(at\.)$` последовательность из строчной `a`, строчной `t`, и точки `.`, ключевой момент в том, что благодаря доллару этот шаблон будет находить совпадения только в том случае, если будет наблюдаться в конце строки. Например: <pre> "(at\.)" => The fat c<a href="#learn-regex"><strong>at.</strong></a> s<a href="#learn-regex"><strong>at.</strong></a> on the m<a href="#learn-regex"><strong>at.</strong></a> </pre> [Запустить регулярное выражение](https://regex101.com/r/y4Au4D/1) <pre> "(at\.)$" => The fat cat. sat. on the m<a href="#learn-regex"><strong>at.</strong></a> </pre> [Запустить регулярное выражение](https://regex101.com/r/t0AkOd/1) ## 3. Наборы сокращений и диапазоны Регулярные выражения предоставляют сокращения для часто используемых наборов символов, которые предлагают удобные сокращения для часто используемых регулярных выражений. Наборы сокращенных символов следующие: |Сокращение|Описание| |:----:|----| |.|Любой символ кроме символа новой строки| |\w|Поиск буквенно-цифрового диапазона символов: `[a-zA-Z0-9_]`| |\W|Поиск не буквенно-цифрового диапазона символов: `[^\w]`| |\d|Поиск цифр: `[0-9]`| |\D|Поиск всего, что не является цифрой: `[^\d]`| |\s|Поиск пробелов и символов начала строки: `[\t\n\f\r\p{Z}]`| |\S|Поиск всего кроме пробелов и символов начала строки: `[^\s]`| ## 4. Опережающие и ретроспективные проверки Опережающие и ретроспективные проверки (в английской литературе lookbehind, lookahead) это особый вид ***не запоминающих скобочных групп*** (находящих совпадения, но не добавляющих в массив). Данные проверки используются когда мы знаем, что шаблон предшествует или сопровождается другим шаблоном. Например, мы хотим получить цену в долларах `$` из следующей входной строки `$4.44 and $10.88`. Для этого используем следующее регулярное выражение `(?<=\$)[0-9\.]*`, означающее получение всех дробных (с точкой `.`) цифр, которым предшествует знак доллара `$`. Существуют следующие виды проверок: |Символ|Описание| |:----:|----| |?=|Положительное опережающее условие| |?!|Отрицательное опережающее условие| |?<=|Положительное ретроспективное условие| |?<!|Отрицательное ретроспективное условие| ### 4.1 Положительное опережающее условие Положительное опережающее утверждение (assert) означает, что за первой частью выражения должно следовать опережающее выражение (lookahead expression). (по аналогии с условиями, if (..) then (..)). Возвращенное совпадение содержит только текст, который соответствует первой части выражения. Для определения положительного опережающего условия используются круглые скобки. В этих скобках используется знак вопроса со знаком равенства: `(?=...)`. Опережающее выражение, записывается в скобках после знака равенства. Рассмотрим пример регулярного выражения: `(T|t)he(?=\sfat)`, обозначающее опциональное наличие строчной `t` или заглавной `T`, следом буквы `h` и `e`. В скобках, мы определяем положительное опережающее условие, которое сообщает движку регулярных выражений информацию о том, что после шаблона `The` или `the` будет следовать слово `fat`. <pre> "(T|t)he(?=\sfat)" => <a href="#learn-regex"><strong>The</strong></a> fat cat sat on the mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/IDDARt/1) ### 4.2 Отрицательное опережающее условие Отрицательное опережающее условие работает по обратному принципу: используется, когда нам нужно получить все совпадения из входной строки, за которыми НЕ следует определенный шаблон. Отрицательное опережающее условие определяется таким же образом, как и позитивное, с той лишь разницей, что вместо равенства `=` мы ставим восклицательный знак `!` (отрицание) например: `(?!...)`. Рассмотрим выражение `(T|t)he(?!\sfat)`, в котором мы находим все `The` или `the` слова из входной строки, за которыми не следует слово `fat`. <pre> "(T|t)he(?!\sfat)" => The fat cat sat on <a href="#learn-regex"><strong>the</strong></a> mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/V32Npg/1) ### 4.3 Положительное ретроспективное условие Положительное ретроспективное условие используется чтобы найти все совпадения, которым предшествует определенный шаблон. Условие определяется как `(?<=...)`. Например, выражение `(?<=(T|t)he\s)(fat|mat)` означает, найти все слова `fat` или `mat` из входной строки, которым предшествует слово `The` или `the`. <pre> "(?<=(T|t)he\s)(fat|mat)" => The <a href="#learn-regex"><strong>fat</strong></a> cat sat on the <a href="#learn-regex"><strong>mat</strong></a>. </pre> [Запустить регулярное выражение](https://regex101.com/r/avH165/1) ### 4.4 Отрицательное ретроспективное условие Отрицательное ретроспективное условие используется чтобы найти все совпадения, которым НЕ предшествует определенный шаблон. Условие определяется как `(?<!...)`. Например, выражение `(?<!(T|t)he\s)(cat)` означает найти все слова `cat` из входной строки, которым не предшествует определенный артикль `The` или `the`. <pre> "(?<!(T|t)he\s)(cat)" => The cat sat on <a href="#learn-regex"><strong>cat</strong></a>. </pre> [Запустить регулярное выражение](https://regex101.com/r/8Efx5G/1) ## 5. Флаги Флаги, также называемые модификаторами, изменяют вывод регулярного выражения. Эти флаги могут быть использованы в любом порядке или комбинации, и являются неотъемлемой частью регулярных выражений. |Флаг|Описание| |:----:|----| |i|Поиск без учета регистра| |g|Глобальный поиск: поиск шаблона во всем входном тексте| |m|Мультистроковый поиск: Якоря применяются к каждой строке.| ### 5.1 Поиск без учета регистра Модификатор `i` используется для поиска без учета регистра. Например, регулярное выражение `/The/gi` означает заглавную `T` следом строчные `h` и `e`. В конце регулярного выражения флаг `i`, указывающий движку регулярных выражений игнорировать регистр. Помимо `i`, для поиска шаблона во всем входном тексте, использован флаг `g`. <pre> "The" => <a href="#learn-regex"><strong>The</strong></a> fat cat sat on the mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/dpQyf9/1) <pre> "/The/gi" => <a href="#learn-regex"><strong>The</strong></a> fat cat sat on <a href="#learn-regex"><strong>the</strong></a> mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/ahfiuh/1) ### 5.2 Глобальный поиск Модификатор `g` используется для выполнения глобального сопоставления (найти все совпадения, а не останавливаться после первого). Например, регулярное выражение `/.(at)/g` означает любой символ кроме символа новой строки, следом строчная `a`, далее строчная `t`. Из-за использования флага `g` в конце регулярного выражения, теперь оно найдет все совпадения во входной строке, а не остановится на первом (что является поведением по умолчанию). <pre> "/.(at)/" => The <a href="#learn-regex"><strong>fat</strong></a> cat sat on the mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/jnk6gM/1) <pre> "/.(at)/g" => The <a href="#learn-regex"><strong>fat</strong></a> <a href="#learn-regex"><strong>cat</strong></a> <a href="#learn-regex"><strong>sat</strong></a> on the <a href="#learn-regex"><strong>mat</strong></a>. </pre> [Запустить регулярное выражение](https://regex101.com/r/dO1nef/1) ### 5.3 Мультистроковый поиск Модификатор `m` используется для многострочного поиска. Как мы обсуждали ранее, якоря `(^, $)` используются для проверки, является ли шаблон началом или концом входной строки. Но если мы хотим, чтобы якоря работали в каждой строке, мы используем флаг `m`. Например, регулярное выражение `/at(.)?$/gm` означает строчную `a`, следом строчная `t` и любой символ кроме начала новой строки, идущий опционально (не обязательно). Из-за флага `m` механизм регулярных выражений будет искать данный шаблон в конце каждой строки в тексте. <pre> "/.at(.)?$/" => The fat cat sat on the <a href="#learn-regex"><strong>mat.</strong></a> </pre> [Запустить регулярное выражение](https://regex101.com/r/hoGMkP/1) <pre> "/.at(.)?$/gm" => The <a href="#learn-regex"><strong>fat</strong></a> cat <a href="#learn-regex"><strong>sat</strong></a> on the <a href="#learn-regex"><strong>mat.</strong></a> </pre> [Запустить регулярное выражение](https://regex101.com/r/E88WE2/1) ## 6. Жадные vs ленивые квантификаторы По умолчанию регулярное выражение выполняет жадное сопоставление, то есть оно будет искать совпадения как можно дольше. Мы можем использовать `?` для ленивого поиска, который будет стремиться быть как можно более коротким по времени. <pre> "/(.*at)/" => <a href="#learn-regex"><strong>The fat cat sat on the mat</strong></a>. </pre> [Запустить регулярное выражение](https://regex101.com/r/AyAdgJ/1) <pre> "/(.*?at)/" => <a href="#learn-regex"><strong>The fat</strong></a> cat sat on the mat. </pre> [Запустить регулярное выражение](https://regex101.com/r/AyAdgJ/2) ## Содействие * Вы можете открыть пулл реквест с улучшением * Обсуждать идеи в issues * Распространять ссылку на репозиторий * Получить обратную связь через [](https://twitter.com/ziishaned) ## Лицензия MIT © [Zeeshan Ahmad](https://twitter.com/ziishaned)