# CookBook по регулярным выражениям (REGEX)

Проверка работы регулярок (выставить флаги gm):

- [https://regexr.com/](https://regexr.com/)
- [https://regex101.com/](https://regex101.com/)

Доп чтиво:

- [https://habr.com/ru/articles/545150/](https://habr.com/ru/articles/545150/)
- [https://regex.sorokin.engineer/ru/latest/regular\_expressions.html](https://regex.sorokin.engineer/ru/latest/regular_expressions.html)

<p class="callout info">В KUMA все группы которые участвуют в маппинге (нормализации) должны быть именованы, пример именования "priority" для группы: `(<strong>?P<priority></strong>\d|\d{2}|1[1-8]\d|19[01])`</p>

<p class="callout info">Если группа не нужна в маппинге, то можно использовать не именованную группу, пример: `(<strong>?:</strong>\d|\d{2}|1[1-8]\d|19[01])`</p>

Простейшие приемы, практику отработаем на тестовом сообщении:

```
Message from 127.0.0.1 (localhost): KUMA is the best SIEM in 2023!
```

### Захватить строку KUMA

`<strong>KUMA</strong>` *Ищется полное соответствие строке KUMA.*

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/oJYimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/oJYimage.png)

### Захватить строку содержащую только буквы

`<strong>[A-Za-z]+</strong>` *Ищем группу (**\[\]**) символов с большими (**A-Z**) и маленькими (**a-z**) буквами от одной и более (**+**).*

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/sOYimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/sOYimage.png)

### Захватить строку содержащую только числа

`<strong>\d+</strong>` *Ищем по токену **\\d**, что является эквивалентом **\[0-9\]** от одного и более вхождений (**+**).*

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/bf3image.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/bf3image.png)

### Захватить строку внутри круглых скобок

`<strong>\((\w+)\)</strong>` *Ищем по токену **\\w**, что является эквивалентом **\[a-zA-Z0-9\_\]** от одного и более вхождений (**+**), при этом экранируем круглые скобки с помощью обратного слеша **\\** и строку нашу определяем в группу круглыми скобками **()***

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/mR9image.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/mR9image.png)

### Захватить строку до двоеточия

`<strong>^[^\:]+</strong>` *Ищем с начала строки **^**, далее захватываем в группе все кроме двоеточия (символ двоеточия экранирован) **\[^\\:\]** от одного и более вхождений (**+**)*

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/p5Ximage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/p5Ximage.png)

### Захватить строку после двоеточия

`<strong>[^\:]+$</strong>` Такая, подобная предствленной выше, конструкция не подойдет, т.к. она будет очень емокой (633 шага). *Ищем все кроме двоеточия (символ двоеточия экранирован) **\[^\\:\]** от одного и более вхождений (**+**), но до конца строки **$***

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/aPvimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/aPvimage.png)

В нашем случае лучше использовать следующее

*`<strong>\:(.*)$</strong>` Ищем в строке двоеточие **\\:**, далее захватываем все символы от нуля и более вхождений (**\***), и берем все что нам нужно в группу **()***

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/cY9image.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/cY9image.png)

### Захватить IP-адрес

`<strong>\d+\.\d+\.\d+\.\d+</strong>` *Ищем числа от одного и более **\\d+**, с точкой и так 4 раза*

[![Untitled.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/untitled.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/untitled.png)

### Захватить слова состоящие из 4 букв

`<strong>\b[a-zA-Z]{4}\b</strong>` *Ищем группу 4 символов из букв и разграничиваем их (boundary) **\\b***

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/cCVimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/cCVimage.png)

### Захватить слова состоящие от 3 до 4 букв

`<strong>\b[a-zA-Z]{3,4}\b</strong>` *Ищем группу 4 символов из букв и разграничиваем их (boundary) **\\b***

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/scaled-1680-/cOcimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-10/cOcimage.png)

### Захватить IPv4 адрес

**`\b((2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9])\.){3}((2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9]))\b`**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/Gioimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/Gioimage.png)

Более ленивый вариант, но быстрый, без валидации:

**`(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})`**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/XXgimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/XXgimage.png)

### Захватить IPv6 адрес

**`(([a-fA-F0-9]{1,4}|):){1,7}([a-fA-F0-9]{1,4}|:) `**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/huCimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/huCimage.png)

### Захватить HASH сумму

- MD **`^[a-fA-F0-9]{32}$`**
- SHA1 **`^[a-fA-F0-9]{40}$`**
- SHA256 **`^[a-fA-F0-9]{64}$`**
- SHA512 **`^[a-fA-F0-9]{128}$`**

### Захватить URL адрес

**`^((https?:\/\/)?([\da-z\.-]+\.[a-z\.]{2,6}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*\S+)$ `**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/p1Timage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/p1Timage.png)

### Захватить EMAIL адрес

Определяет почти все типы валидных адресов

**`\b[\w\.\-\+\!\/\"\%]+@[\w\.-]+(\.\w{2,4})?\b`**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/uDRimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/uDRimage.png)

### Захватить CSV структуру

Создаются группы по значениям из CSV

**`(?:\s*(?:\"([^\"]*)\"|([^,]+))\s*,?)+?`**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/Byyimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/Byyimage.png)

### Захватить Syslog структуру

Разбираются сообщения по rfc [https://datatracker.ietf.org/doc/html/rfc5424](https://datatracker.ietf.org/doc/html/rfc5424) и [https://datatracker.ietf.org/doc/html/rfc3164](https://datatracker.ietf.org/doc/html/rfc3164)

**`(?P<syslog>^<(?P<priority>\d|\d{2}|1[1-8]\d|19[01])>(?P<version>\d{1,2})?\s?(?P<timestamp>(?P<rfc3164>[A-Z][a-z][a-z]\s{1,2}\d{1,2}\s\d{2}[:]\d{2}[:]\d{2})|(?P<rfc5424>\d{4}[-]\d{2}[-]\d{2}[T]\d{2}[:]\d{2}[:]\d{2}(?:\.\d{1,6})?(?:[+-]\d{2}[:]\d{2}|Z)?))\s?(?P<hostname>[\S]{1,255})\s?(?P<appname>[\/\w-]{1,48})?\s?\[?(?P<procid>[\w]{1,128})?(?P<delimMSG>\]\:\s|\s\-\s|\:\s|\s)(?P<BIGmsg>(?P<msgid>[\S]{1,32})?(?P<delimMSGID>\]\:\s|\s\-\s|\:\s|\s)?(?P<structureddata>\[.+[\]]+|-)?(?:\s(?P<msg>.+))?)$)`**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/2Cgimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/2Cgimage.png)

### Захватить символы (не буквы и не цифры)

**`[^\w \xC0-\xFF]`**

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/scaled-1680-/3uGimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2023-11/3uGimage.png)

### Работа с многострочным сообщением

В regexp существуют следующие флаги:

- `i` - нечувствителен к регистру (по умолчанию false)
- `m` - многострочный режим, ^ и $ соответствуют строке начала/конца в дополнение к тексту начала/конца (по умолчанию false)
- `s` - позволяет `.` (точке) совпадать с `\n` (по умолчанию false)
- `U` - не жадный режим, меняет местами значения x\* и x\*?, x+ и x+? и т. д. (по умолчанию false)

Синтаксис флага: xyz (установить) или -xyz (очистить) или xy-z (установить xy, очистить z).

Устанавливаем флаг s

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2024-03/scaled-1680-/nTgimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2024-03/nTgimage.png)

Использование в KUMA:

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2024-03/scaled-1680-/jcsimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2024-03/jcsimage.png)

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2024-03/scaled-1680-/CxFimage.png)](https://kb.kuma-community.ru/uploads/images/gallery/2024-03/CxFimage.png)

### Замена разделителя в структуре KV

Иногда в структуре KV разделитель пробел создает нам проблемы, пример такого события:

```bash
pid=\"29753\" appname=\"DBeaver 23.2.1 - SQLEditor <Script-40.sql>\" user=\"user2\" dbname=\"test_db\" rhost=\"comp.local(911)\" queryid=\"0\" command_tag=\"BIND\" sql_state=\"42501\" session_id=\"6662a086.7439\" session_seq=\"74\" session_start_time=\"2024-06-07 05:54:14 UTC\" virt_trans_id=\"5/231\" trans_id=\"0\" msg=STATEMENT: select lo_export(111,'/tmp/pido')
```

В примере значение по ключу msg без кавычек, и оно будет некорректно парситься, поэтому можно, либо заменами добавить эти кавычки, либо воспользоваться приемом полегче и сделать разделитель, например |

Для этого используем функцию replaceWithRegexp:

![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2024-06/scaled-1680-/image.png)

Вот как выглядит будет замена:

![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2024-06/scaled-1680-/SY2image.png)

Вот как это выглядит в KUMA:

![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2024-06/scaled-1680-/BXjimage.png)

### Общая шпаргалка

[![image.png](https://kb.kuma-community.ru/uploads/images/gallery/2024-12/scaled-1680-/image.png)](https://kb.kuma-community.ru/uploads/images/gallery/2024-12/image.png)