# Регулярные выражения

1. [Введение в регулярные выражения в современном C++](https://habr.com/ru/companies/otus/articles/532056/)
2. [!!! Learn Регулярные выражения](https://learn.javascript.ru/regular-expressions)
3. [Atomic Grouping - ?>](https://www.regular-expressions.info/atomic.html)
4. [Опережающий поиск (lookahead) и ретроспективный поиск (lookbehind) - ?=/?<=](https://ru.hexlet.io/courses/regexp/lessons/lookaround/theory_unit)

Регулярные выражения (их еще называют regexp, или regex) — это механизм для поиска и замены текста/гибкий поискоывй язык . В строке, файле, нескольких файлах... Их используют разработчики в коде приложения, тестировщики в автотестах, да просто при работе в командной строке!

![Regex structure](https://rufri.ru/wp-content/uploads/2018/11/reg.jpg)

[Пример](/1%20Common/1.2%20Git/1.2.5%20GitHook/1.2.5.2%20commit-msg.md) использования регулярки - `PATTERN="(^\[[\w]{1}[a-z]{3,4}\-[\d]+\] |^(tech:))"`. 1 или 2 условие:

 1. Начиная с новой строки - `^` - ищем вхождение экранированной(`\`) кв. скобки `[` и после любую букву (или слово) - `[\w]` - но только одно - `{1}` - плюсуя к этому любые маленькие буквы - `[a-z]` - в объеме 3 или 4 штук - `{3,4}` - плюсуя к этому экранированную(`\`) тире - `-` - плюсуя к этому любые цифры в любом количестве - `[\d]+` - + экранированной(`\`) кв. скобки `]` добавляя к этому в конце пробел ` `.
 2. Начиная с новой строки - `^` -  полное совпадение слову `tech:` -  `(` и `)`.

Подходят:

```swift
[Front-1234567890] 
[Back-1] 
[back-1] 
tech: 
```

Попрактиковаться можно [здесь](https://regex101.com/).

![RegexSpreadsheet](/pictures/Common/Regex/RegexSpreadsheet.jpg?raw=true)

> Важное замечание 1. Регулярные выражения зависимы от регистра, то есть «А» и «а» при поиске будут считаться разными символами.

> Важное замечание 2. Буквы «Ё» и «ё» не входят в диапазон «А — Я» и «а — я». Так что, задавая русский алфавит, их нужно выписывать отдельно.

## Задачи для практики

#### 1) Найдите неотрицательные целые

Есть строка с целыми числами.

Создайте регулярное выражение, которое ищет только неотрицательные числа. Ноль разрешён.

Пример использования:

```bash
let regexp = /ваше регулярное выражение/g;

let str = "0 12 -5 123 -18";

alert( str.match(regexp) ); // 0, 12, 123
```

<details><summary>Решение</summary>
<p>

Регэксп для целого числа: `\d+`.

Мы можем исключить отрицательные добавлением негативной ретроспективной проверки: `(?<!-)\d+`.

Однако, если попробуем применить такой регэксп, то увидим лишний результат:

```js run
let regexp = /(?<!-)\d+/g;

let str = "0 12 -5 123 -18";

console.log( str.match(regexp) ); // 0, 12, 123, 8
```

Как видите, оно находит `8` из `-18`. То есть, берёт только цифру из числа `-18`, так как это формально подходит под регулярное выражение.

Чтобы исключить такой вариант, надо убедиться, что регэксп не будет искать число с середины другого (неподходящего) числа.

Мы можем сделать это добавлением ещё одной проверки: `(?<!-)(?<!\d)\d+`. Теперь `(?<!\d) гарантирует, что поиск не начнётся после цифры.

Можем объединить проверки в одну:

```javascript
let regexp = /(?<![-\d])\d+/g;

let str = "0 12 -5 123 -18";

alert( str.match(regexp) ); // 0, 12, 123
```

</p>
</details>

#### 2) Любое число от 1 до 50 включительно

`(^[1-9]{1}$|^[1-4}{1}[0-9]{1}$|^50$)` 

#### 3) Адрес email

`(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})`

#### 4) От 8 до 15 символов с минимум одной цифрой, одной заглавной и одной строчной буквой

> Полезно для паролей

`((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,15})`

---

[1.3.3 Command Line Tools (CLI) Folder](../1.3.3%20CLI/) | [Back To iTWiki Contents](https://github.com/eldaroid/iTWiki) |  [1.3.4.2 Greedy And Lazy Search Theme](./1.3.4.2%20GreedyAndLazySearch.md)
