# Шпаргалка по регулярным выражениям

<div align="right"><a href="https://github.com/cheatsnake/backend-cheats#%D0%BE%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-%D1%8F%D0%B7%D1%8B%D0%BA%D0%B0">Вернуться на главную страницу ⬆️</a></div>

**Содержание:**

- [Базовое применение](#базовое-применение)
- [Флаги](#флаги)
- [Основной синтаксис](#основной-синтаксис)
  - [Любой символ .](#любой-символ-)
  - [Перечень []](#перечень-)
  - [Исключающий перечень [^]](#исключающий-перечень-)
  - [Диапазон [-]](#диапазон--)
  - [Повторения *](#повторения-)
  - [Повторения +](#повторения--1)
  - [Необязательный символ ?](#необязательный-символ-)
  - [Количество повторений {}](#количество-повторений-)
  - [Диапазон повторений {,}](#диапазон-повторений-)
  - [Группировка ()](#группировка-)
  - [Логическое ИЛИ |](#логическое-или-)
  - [Экранирование](#экранирование-)
  - [Поиск в начале строки ^](#поиск-в-начале-строки-)
  - [Поиск в конце строки $](#поиск-в-конце-строки-)
  - [Классы символов](#классы-символов)
  - [Позиционные проверки](#позиционные-проверки)


[Регулярные выражения](https://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F) – это мощный инструмент для поиска и замены слов в тексте. Само регулярное выражение представляет из себя обычную строку составленную по определенным правилами. В общем виде она представляет из себя две косые черты `/ /`, где после первой черты идёт специальный паттерн для поиска, а после второй – набор флагов.

Для тренировки использования регулярных выражений можно воспользоваться сайтом [Regex101.com](https://regex101.com/).

Также можно воспользоваться возможностями для работы с регулярными выражениями в одном из языков программирования. Вот примеры для [Python](https://pythonru.com/primery/primery-primeneniya-regulyarnyh-vyrazheniy-v-python), [JavaScript](https://developer.mozilla.org/ru/docs/Web/JavaScript/Guide/Regular_Expressions), [Go](https://tproger.ru/articles/puteshestvie-v-golang-regexp/), [Kotlin](https://java-blog.ru/kotlin/vvedenie-v-regulyarnye-vyrazheniya-kotlin), [C#](https://metanit.com/sharp/tutorial/7.4.php) и [так далее](https://www.google.com/search?q=%D0%BA%D0%B0%D0%BA+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C+%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5+%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F+%D0%B2+%5B%D0%B2%D0%B0%D1%88+%D1%8F%D0%B7%D1%8B%D0%BA+%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%5D%5D)

## Базовое применение

Возьмем для примера любой текст. Представим, что в этом тексте нам нужно найти все слова `London`. Это самый простой случай использования регулярных выражения, нам всего лишь необходимо вписать нужное слово между косыми чертами:

<p align="center"><img src="https://i.ibb.co/cCsd7ss/Pasted-image-20221016151349.png" alt="Regex example"/></p>

## Флаги

Флаги влияют на результат поиска. Их всего 5 штук:

-   `i` – позволяет игнорировать регистры букв (нет разницы между *A* и *a*).
-   `g` – позволяет искать все совпадения в тексте, без него – только первое.
-   `m` – включение многострочного режима (влияет только на поведение `^` и `$`).
-   `s` – текст трактуется как одна строка, в этом случае метасимволу `.` (точка) соответствует любой одиночный символ, включая символ новой строки.
-   `u` – unicode-трактовка. Выражение может содержать специальные паттерны, характерные для юникода.

## Основной синтаксис

### Любой символ `.`

На месте точки может быть любой символ. Количеством точек можно определять длину слов.

```js
/t..k/g
```

> take look team <ins>took</ins> hike track <ins>teak</ins> time

### Перечень `[]`

Позволяют указать определенный перечень символов.

```js
/t[aoi]k/g
```

> tek <ins>tok</ins> tdk <ins>tak</ins> <ins>tik</ins> tuk tyk took taoik

### Исключающий перечень `[^]`

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

```js
/ba[^td]/g
```

> <ins>ban</ins> <ins>bag</ins> bat <ins>bas</ins> bad

### Диапазон `[-]`

Указывает диапазон с первого по последний символ (включительно) в алфавитном порядке.

```js
/[a-d]../g
```

> ost hst <ins>ast</ins> fst <ins>cst</ins> <ins>bst</ins>

Аналогично работает с цифрами:

```js
/201[5-9]/g
```

> 2010 2012 <ins>2015</ins> <ins>2017</ins> <ins>2019</ins> 2022

### Повторения `*`

Звездочка после символа указывает, что данный символ может отсутствовать, либо совпадать один или более раз.

```js
/wo*w/g
```

> <ins>wow</ins> waw wiw <ins>woooow</ins> wawe <ins>ww</ins> <ins>woow</ins>

### Повторения `+`

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

```js
/go+gle/g
```

> <ins>google</ins> ggle <ins>gogle</ins> gugle g00gle <ins>goooogle</ins>

### Необязательный символ `?`

Вопросительный знак после символа указывает, что данный символ является не обязательным (может либо отсутствовать, либо встрачаться только один раз).

```js
/bou?nd/g
```

> <ins>bond</ins> <ins>bound</ins> bouuund boynd

### Количество повторений `{}`

Чтобы указать точное количеcтво повторений, необходимо после символа записать фигурные скобки с нужным числом.

```js
/bo{3}m/g
```

> boom bom <ins>booom</ins> bm boooom

### Диапазон повторений `{,}`

Чтобы указать диапазон повторений, необходимо после символа записать фигурный скобки с нужным диапазоном, разделенным запятой.

```js
/lo{2,4}k/g
```

> lok <ins>look</ins> lk <ins>loook</ins> <ins>looook</ins> loooooook

Верхнюю границу можно опускать. Например, запись `a{3,}` говорит о том, что символ _a_ должен встречаться не менее трёх раз.

### Группировка `()`

Скобки позволяют сгруппировать любую последовательность символов, чтобы в дальнейшем обращается к ним используя выражение `\число`, где число - порядковый номер сгруппированной последовательности.

```js
/(la)-\1{2}-\1{3}/g // Группируем выражение "la" и затем, обращаемся к нему через "\1"
```

> la-laaa-<ins>la-lala-lalala</ins>-lalala-la-la-la

```js
/(la)-\1-(laa)-\2/g
```

> laa-la-laa-<ins>la-la-laa-laa</ins>-lalal

Чтобы игнорировать сохранение группы используется конструкция `(?:)`.

```js
/(?:abc)-(test),\1,\1/g // В данном случае группа "abc" не будет сохранена, поэтому первый индекс указывает на "test".
```

> abc,test-<ins>abc-test,test,test</ins>-abc-test

Группам можно задавать любые имена. Для этого используется конструкция - `(?P<Name>...)`, где Name - название, ... - любая последовательность символов. Для обращения к именованным группам используется конструкция - `(?P=Name)`.

```js
/(?P<seven>7{3})-(?P=seven){2}-(?P=seven)/g
```

> 7777-77-7777777-<ins>777-777777-777</ins>-777-7-7-7-7777-7

Если у Вас возникли трудности с пониманием группировки, советую [посмотреть данное видео](https://youtu.be/W9CffcsYpAU).

### Логическое ИЛИ `|`

Вертикальная черта позволяет указывать альтернативные варианты для поиска. Это чем-то похоже на использование квадратных скобок `[abc]`, но только вертикальная черта может работать с целыми словами и выражениями, а не только с отдельными символами.

```js
/yes|no/g
```

> <ins>yes</ins>,maybe,<ins>no</ins>,idk,ok

### Экранирование `\`

Для того, чтобы использовать в поиске специальные символы `{} [] / \ + *. $ ^ |?`, необходимо поставить впереди знак косой черты `\`.

```js
/\.|\?/g // Поиск точек "." или знаков вопроса "?"
```

> What now<ins>?</ins> What next<ins>?</ins> Times up<ins>.</ins> Wake up<ins>.</ins> 

### Поиск в начале строки `^`

Символ каретки в регулярном выражении говорит о том, что поиск производится только по началу строк.

```js
/^[0-9]*/gm // Поиск чисел которые находятся в начале строки
```

> <ins>1</ins>. Apples x10 <br>
> <ins>2</ins>. Cookies x5 <br>
> <ins>3</ins>. Eggs x7

### Поиск в конце строки `$`

Символ доллара в регулярном выражении говорит о том, что поиск производится только по концу строк.

```js
/com|net/gm
```

> google.<ins>com</ins> <br>
> nodejs.org <br>
> sourceforge.<ins>net</ins>

### Классы символов

Для более удобного поиска целого класса символов существуют встроенные обозначения.

#### Любой словесный символ `\w`

Обе записи ниже эквивалентны.

```js
/[a-zA-Z0-9_]/g
```

```js
/\w/g
```

> <ins>some</ins> <ins>random</ins> <ins>words</ins> <ins>for</ins> <ins>example</ins>

#### Любой не словесный символ `\W`

```js
/[^a-zA-Z0-9_]/g
```

```js
/\W/g
```

> developer_2022<ins>@</ins>gmail<ins>.</ins>com

#### Любая цифра `\d`

```js
/[0-9]/g
```

```js
/\d/g
```

> developer_<ins>2022</ins>@gmail.com

#### Любой символ кроме цифр `\D`

```js
/[^0-9]/g
```

```js
/\D/g
```

> <ins>developer_</ins>2022<ins>@gmail.com</ins>

#### Пробел `\s`

К пробелам также относятся различные символы переноса строк.

```js
/[\r\n\t\f\v ]/g
```

```js
/\s/g
```

#### Любой символ кроме пробела `\S`

```js
/[^\r\n\t\f\v ]/g
```

```js
/\S/g
```

### Позиционные проверки

Для того, чтобы найти фразу, которая должна находится до или после другой фразы используются позиционные проверки (lookarounds).

#### Опережающие проверки `(?=)` `(?!)`

Чтобы найти выражение Х после которого стоит выражение Y, используется конструкция `X(?=Y)`.

```js
/\d+(?=€)/g
```

> 200$ <ins>750</ins>€ 100$ <ins>330</ins>€ 550$

Чтобы найти выражение Х после которого НЕ стоит выражение Y, используется конструкция `X(?!Y)`.

```js
/\d{4,}(?!€)/g
```

> This car was costed about 7000€ in <ins>2015</ins>

#### Ретроспективные проверки `(?<=)` `(?<!)`

Чтобы найти выражение X перед которым стоит выражение Y, используется конструкция `(?<=Y)X`.

```js
/(?<=:)\d+/g 
```

> {"id":<ins>4</ins>,"value":<ins>123</ins>,name:"test"}

Чтобы найти выражение X перед которым НЕ стоит выражение Y, используется конструкция `(?<!Y)X`.

```js
/(?<!\$)\d+/g
```

> $5 $6 $7 <ins>2019</ins> <ins>2009</ins> <ins>1999</ins>


## Практика

Потратьте немного времени на закрепление изученного материала. Напишите простую библиотеку на Вашем любимом языке программирования, которая будет выполнять валидации (проверки) заданных строк. Например, на соответствие электронной почты или номера телефона. Напишите валидатор для паролей, чтобы он соответствовал заданным требованиям по длине, наличию специальных символов, заглавных букв или цифр. Это будет вдвойне полезным занятием, поскольку в будущем вы сможете использовать эту библиотеку в Ваших приложениях.

Дополнительно по запросу в Google – _regex practice_, можно найти много интересных заданий на тему регулянрых выражений.

## Дополнительные материалы

1. 📄 [**Awesome Regex** – GitHub](https://github.com/aloisdg/awesome-regex)
1. 📺 [**Регулярные выражения в SEO: где и как применяются** – YouTube](https://youtu.be/ZxWfQW32dIE)
1. 📘 [**Регулярные выражения. Сборник рецептов** – Ян Гойвертс, Стивен Левитан, 2010](https://www.litmir.me/data/Book/0/156000/156298/Goiverts_Yan_Regulyarnye_vyracheniya._Sbornik_receptov_%5BPodrobnye_resheniya_na_vosmi_yazykah_programmirova_Litmir.net_bid156298_original.pdf)
