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

Регулярные выражения — рецепты и командная строка

Разработчику Инженеру Аналитику Тестировщику

Предыдущие шаги: введениесинтаксисгруппыпроверкифлаги.


Как пользоваться этой статьей

Каждый рецепт — стартовая точка, не промышленный стандарт. Перед продакшеном прогоните шаблон на своих данных в лаборатории, в готовых паттернах с разбором или на regex101.com с тем движком, который будете использовать (JavaScript, PCRE, .NET).

Формат разбора:

ПолеСодержание
Шаблончто вводить
Разборсмысл блоков (см. синтаксис)
Пример текстаоткуда копировать тест
Командаgrep, rg, PowerShell
Ограничениякогда regex лучше заменить кодом или парсером
Сборка с нуля

Если шаблон кажется магией — разберите его по синтаксису с нуля — якоря, классы, квантификаторы. Рецепт здесь — уже собранный конструктор.


Email

Проверка поля формы (вся строка):

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
БлокСмысл
^...$один адрес на строку
[a-zA-Z0-9._%+-]+локальная часть
@разделитель
[a-zA-Z0-9.-]+домен
\.[a-zA-Z]{2,}зона

Поиск всех адресов в абзаце — без ^ $:

[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
ТестОжидание
user@example.comда / найдено
a@b.coда
user@.comнет

Команда:

rg -o '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' contacts.txt

-o — только совпавший фрагмент. Для UI-формы достаточно упрощения; доставка письмом — отдельная проверка.


Телефон +7 (Россия, гибко)

Поиск в тексте (скобки, пробелы, дефисы опциональны):

\+7\s?\(?\d{3}\)?\s?\d{3}[-\s]?\d{2}[-\s]?\d{2}

Строгий формат +7 916 555-12-34:

^\+7\s(\d{3})\s\d{3}-\d{2}-\d{2}$
ГруппаПоле
1код оператора

Пример текста:

Звоните +7 (916) 555-12-34 или +79165551234

Команда:

rg -o '\+7\s?\(?\d{3}\)?\s?\d{3}[-\s]?\d{2}[-\s]?\d{2}' page.html

Международные номера и внутренние добавочные — отдельные шаблоны или библиотека libphonenumber.


URL

https?://[^\s<>"']+
БлокСмысл
https?http или https
://литерал
[^\s<>"']+до пробела или кавычек

Пример:

См. https://example.com/path?q=1 и http://test.local

Команда:

rg -o 'https?://[^[:space:]<>"']+' README.md

Query-параметры с & и кодировкой %20 шаблон обычно тянет; фрагмент #section — тоже. Проверка "живого" URL — HTTP-запросом, не regex.


Дата в разных форматах

Поиск в тексте (гибко):

\b\d{1,2}[./-]\d{1,2}[./-]\d{2,4}\b

Строго ДД-ММ-ГГГГ (форма):

^(?<day>\d{2})-(?<month>\d{2})-(?<year>\d{4})$

Именованные группы — Регулярные выражения — группы и замена. Замена в 22.01.2026: $<day>.$<month>.$<year> в .NET / VS Code.

ISO дата:

\b\d{4}-\d{2}-\d{2}\b

Команда — строки лога за 2026-01-22:

grep -E '^2026-01-22' application.log
rg '^2026-01-22' logs/

Время ISO 8601

\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?\b
БлокСмысл
Tразделитель даты и времени
(?:\.\d+)?доли секунды
(?:Z|...)?UTC или смещение

Пример: 2026-01-22T14:30:05.123Z

Команда:

rg '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}' events.jsonl

Строка лога (классический формат)

2026-01-22 14:30:05 [ERROR] Connection timeout host=10.0.0.5

Разбор всей строки:

^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+\[(\w+)\]\s+(.+)$
ГруппаПоле
1дата
2время
3уровень
4сообщение

Только ERROR:

grep -E '\[ERROR\]' application.log
rg -n '\[ERROR\]' logs/

ERROR и WARN:

rg '\[(ERROR|WARN)\]' logs/

С контекстом (3 строки до и после):

grep -E -C 3 '\[ERROR\]' application.log
rg -C 3 '\[ERROR\]' logs/

Извлечь IP из хвоста (упрощённо):

host=(\d{1,3}(?:\.\d{1,3}){3})

Пресет Строка лога — в лаборатории.


Nginx / Apache

Nginx combined (фрагмент):

203.0.113.1 - - [22/Jan/2026:14:30:05 +0000] "GET /api HTTP/1.1" 500 1234

Код ответа 5xx:

" (5\d{2})

Команда:

rg '" (5\d{2}) ' /var/log/nginx/access.log

Полный разбор access.log — десятки полей; для аналитики часто берут awk или специализированные парсеры. Regex хорош для быстрого фильтра при инциденте. Типовые конфиги nginx и проверка curlNginx — конфиги под задачу.


IPv4 (черновик)

\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b
ОграничениеПояснение
999.999.999.999пройдёт по regex, нет по смыслу
CIDR 10.0.0.0/8нужен отдельный шаблон

Строже октет 0–255 — уже в шаблоне через альтернативы; семантика сети — в коде.

Команда:

rg -o '\b(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\b' dump.txt

Пресет IPv4лаборатория.


MAC-адрес

\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\b

Пример: AA:BB:CC:DD:EE:FF, AA-BB-CC-DD-EE-FF

rg -i '[0-9A-Fa-f]{2}[:-](?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}' inventory.txt

UUID

\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b

Пример: 550e8400-e29b-41d4-a716-446655440000

rg -o '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}' traces.log

Версия и variant UUID — в коде, не в regex.


Семантическое версионирование (semver)

\b(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?\b

Примеры: 1.2.3, 2.0.0-beta.1, 1.0.0+build.42

rg 'v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)' CHANGELOG.md

Git commit (short hash)

\b[0-9a-f]{7,40}\b

Осторожно: совпадёт с любой hex-строкой нужной длины. Сузьте контекст:

\bcommit [0-9a-f]{7,40}\b
rg 'commit [0-9a-f]{7,40}' build.log

Хештег

#[\w\u0400-\u04FF]+

Примеры: #news, #новости

rg -o '#[\w\u0400-\u04FF]+' posts.txt

Серийный номер

\b[A-Z]{3}-\d{4}-[A-Z]{2}\b

Пример: ABC-2026-XZ

Для своего формата замените длины: [A-Z]&#123;2,5&#125;-\d&#123;6,10&#125;.


Повтор слова (опечатка)

\b(\w+)\s+\1\b

Пример: ошибка ошибка в тексте

rg '\b(\w+)\s+\1\b' draft.md

\1группы и замена. Для кириллицы замените \w+ на [а-яА-ЯёЁ\w]+.


JSON-поле (одна строка, упрощённо)

Значение "id": 123 или "id": "abc":

"id"\s*:\s*("([^"\\]|\\.)*"|\d+)
ОграничениеПояснение
Вложенный JSONregex ломается
Многострочный pretty-printнужен jq

Надёжно:

jq '.id' response.json

Regex уместен для grep по логу, где JSON в одну строку:

rg '"level"\s*:\s*"ERROR"' api.jsonl

HTML-теги (грубо)

<[^>]+>

Удаление простых тегов без < внутри. Вложенная разметка — парсер DOM.

Атрибут href:

href="([^"]+)"

Группа 1 — URL в кавычках.


Ключ и значение в конфиге

# comment
db.host=127.0.0.1
db.port=5432
^([a-zA-Z0-9_.-]+)=(.*)$

Пропустить комментариипроверки: ^(?!\s*#).

grep -E '^[a-zA-Z0-9_.-]+=.' app.conf
rg '^(?!\s*#)([a-zA-Z0-9_.-]+)=(.*)$' config/

CSV (одна строка без кавычек внутри полей)

^([^,]+),([^,]+),([^,]+)$

Три колонки. Реальный CSV с "поле, с запятой" — модуль csv в Python, не regex.


Кредитная карта (маскирование, не валидация)

Группы по 4 цифры:

\b(?:\d{4}[-\s]?){3}\d{4}\b

Огранение: не проверяет алгоритм Луна; для PCI — токенизация, не логирование полного номера. В логах ищут утечки маски:

rg '(?:\d{4}[-\s]?){3}\d{4}' *.log

Паспорт РФ (серия и номер, формат)

\b\d{4}\s?\d{6}\b

Пример: 4509 123456. Проверка контрольных цифр — в коде; regex — только формат в тексте.


Windows-путь в логе

[A-Za-z]:\\(?:[^\\\n]+\\)*[^\\\n]+

Пример: C:\Logs\app\error.log

Select-String -Path 'C:\logs\*.log' -Pattern '[A-Za-z]:\\[^\n]+'

Stack trace (Java, фрагмент)

^\s+at\s+[\w.$]+\([\w.]+\.java:\d+\)

Команда:

rg '^\s+at\s+' crash.txt

Командная строка — обзор

С нуля (что такое grep, findstr, Select-String, конвейеры) — поиск текста в файлах. Ниже — флаги и рецепты для тех, кто уже знаком с инструментами.

ИнструментОСRegexКогда
grep -EUnix, Git Bash, WSL; Windows Preview — Microsoft CoreutilsEREодин файл, фильтр
rgкроссплатформенноRust regexдерево проекта
sed -EUnixEREзамена в файле
awkUnixполяфиксированные разделители
findstrWindows (CMD)упрощённыйбыстрый поиск
PowerShellWindows.NETлоги, скрипты

Подробнее про терминал — раздел "Терминал" и поиск в файлах; про rgпродвинутый софт.


grep

ЗадачаКоманда
EREgrep -E 'WARN|ERROR' file.log
Без учёта регистраgrep -Ei 'error' file.log
Номера строкgrep -En 'pattern' file.log
Обратный фильтрgrep -Ev 'DEBUG' file.log
Только совпадениеgrep -Eo 'pattern' file.log
Контекстgrep -E -B2 -A5 'ERROR' file.log
Рекурсивноgrep -rE 'pattern' ./logs/

Без -E символы +, ?, |, &#123;n&#125; могут трактоваться как литералы (зависит от системы). На macOS BSD grep слабее GNU — предпочтительен rg или ggrep из Homebrew.

Подсчёт строк с ERROR:

grep -cE '\[ERROR\]' application.log

ripgrep (rg)

rg -n 'TODO|FIXME' --type py
rg -i 'connection timeout' .
rg --glob '*.log' '\[ERROR\]'
rg -l 'password\s*=' . # только имена файлов
rg -U 'BEGIN.*END' multiline.txt # многострочный режим
rg --replace '$2.$1.$3' -r '$3.$2.$1' -e '(\d{4})-(\d{2})-(\d{2})' dates.txt
ФлагСмысл
-nномер строки
-iбез учёта регистра
-lтолько файлы
-cсчётчик
--globфильтр путей
-U. включает \n

По умолчанию уважает .gitignore — удобно в репозитории.


sed

Замена первого вхождения в строке:

sed -E 's/(\d{4})-(\d{2})-(\d{2})/\3.\2.\1/' dates.txt

Все вхождения в строке (g):

sed -E 's/ERROR/WARN/g' app.log

На месте (бэкап на macOS — sed -i ''):

sed -E -i.bak 's/old/new/g' file.txt

Перед массовой правкой — копия файла и тест на фрагменте.


awk — поля по разделителю

awk '/\[ERROR\]/ { print $1, $2, $NF }' application.log

Третье поле времени, последнее — часто хвост сообщения (зависит от формата).

CSV (простой):

awk -F',' '{print $1, $3}' data.csv

Regex нужен, когда поля "плывут" или нужна маска внутри одного поля.


findstr (Windows)

findstr /R /C:"\[[Ee][Rr][Rr][Oo][Rr]\]" C:\logs\*.log
findstr /N /I "timeout" C:\logs\*.log

/R — regex (ограниченный). /N — номера строк. /I — регистр.


PowerShell (Windows)

Select-String -Path 'C:\logs\*.log' -Pattern '\[ERROR\]'
Get-Content 'C:\logs\app.log' | Select-String -Pattern 'host=(\d+\.\d+\.\d+\.\d+)'

Замена в строке:

'2026-01-22' -replace '(\d{4})-(\d{2})-(\d{2})', '$3.$2.$1'

Синтаксис групп — как в .NET (C#).


Bash — условие

if [[ $file =~ ^data_[0-9]{4}\.csv$ ]]; then
echo "Подходит под шаблон бэкапа"
fi

См. справочник Bash.


Perl one-liner (замена по stdin)

perl -pe 's/(\d{4})-(\d{2})-(\d{2})/$3.$2.$1/g' dates.txt

Полезно, когда sed ведёт себя по-разному на разных ОС, а Perl уже установлен.


Кейс — разбор инцидента за пять минут

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

  1. Сузить файл и время:
rg '\[ERROR\]' logs/ --glob '*2026-01-22*'
  1. Вытащить уникальные сообщения:
rg -o '\[ERROR\]\s+\K.+' logs/app.log | sort | uniq -c | sort -rn | head

(\K в PCRE "сбрасывает" начало совпадения — в rg работает.)

  1. Найти IP или request id:
rg 'request_id=[a-f0-9-]+' logs/app.log
  1. Перейти в код по стабильной фразе из сообщения.

Regex здесь — скальпель, не замена мониторинга (Grafana, Sentry и т.д.).


Различия движков

ВозможностьJavaScript.NETPython regrep -EPCRE
\d, \wдададаGNU дада
Именованные (?<n>…)дада(?P<n>…)редкода
Lookbehindдададаограниченнода
Флаг gдаMatchesfindall
Ленивый *?дадададада
\Kнетнетнетнетда (rg)
ТаймаутнетMatchTimeoutнет (см. сторонние)лимиты

Всегда смотрите документацию своего инструмента. Шаблон с regex101 для PCRE может слегка отличаться в JavaScript.


Типичные ошибки новичка

ОшибкаЧто происходитЧто делать
Забыли ^ $ в формеxok проходит как emailякоря
Точка без экранирования. = любой символ\.
Жадный .*одно огромное совпадение.*? или [^>]*
\w для русскогокириллица выпадает[а-яА-ЯёЁ]
Парсить JSON/HTML regexломается на вложенностиjq, DOM
Шаблон из интернетаReDoS, сложностьупростить, тест
Двойные слэши в коде\ddr"..." / @"..."
grep без -E| как литералgrep -E или rg
Экранирование в shellшаблон обрезанодинарные кавычки '...'

ReDoS — когда regex "зависает"

Шаблон (a+)+$ на длинной строке из a может считаться экспоненциально долго. В пользовательском вводе избегайте вложенных жадных + на повторяющихся группах. В .NET задайте MatchTimeout; подробнее — конечные автоматы.


Рабочий процесс

  1. Сформулировать задачу словами.
  2. Режим — поиск или вся строка (^ $ для форм).
  3. Собрать по Регулярные выражения — синтаксис с нуля; группы — Регулярные выражения — группы и замена; условия — Регулярные выражения — проверки вокруг совпадения; флаги — Регулярные выражения — флаги и жадность.
  4. Тест на реальных и "злых" строках.
  5. Лаборатория / regex101 с нужным движком.
  6. Перенос в код или CLI; в коде — комментарий к шаблону.
  7. Для ввода пользователя — лимит длины и таймаут.

Чек-лист перед продакшеном

ВопросДействие
Валидация поля?^ и $
Все вхождения?g / findall / Matches
Кириллица?проверить \w
Вложенные структуры?парсер
Чужой шаблон?упростить, нагрузочный тест
Логи в проде?не хранить PII, найденные regex-ом

Связь с разделом "Алгоритмы"

Регулярные выражения — сопоставление с регулярным языком (тип 3 в иерархии Хомского). Универсальный цикл программы — Алгоритм обработки.

Синтаксис по кирпичикам — Регулярные выражения — синтаксис с нуля. Введение и лаборатория — Регулярные выражения. Готовые шаблоны с кодом Python/JS — Regex — готовые паттерны.


← К оглавлению раздела "Регулярные выражения"

Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.