| 1 | <!-- kb_card |
| 2 | id: kb-regex-flavors-practice-v1 |
| 3 | title: Regex — диалекты, .NET, практика (L2) |
| 4 | cluster: regex-friedl-mre3 |
| 5 | kb_layer: L2 |
| 6 | book_alignment: Идея «разных движков в разных языках» и практические главы MRE; без переноса vendor-specific страниц. |
| 7 | last_reviewed_utc: 2026-03-21 |
| 8 | --> |
| 9 | |
| 10 | # Regex: диалекты и практика (L2) |
| 11 | |
| 12 | ## Назначение |
| 13 | |
| 14 | Сопоставить **одну задачу** с **конкретным API**: опции, флаги, отличия ECMAScript / PCRE / .NET / Java. Снизить риск «скопировал со Stack Overflow — в моём языке не работает». |
| 15 | |
| 16 | ## Инварианты |
| 17 | |
| 18 | - Нет единого «стандарта regex» для всех фич; всегда сверяй с документацией целевого движка. |
| 19 | - Флаги в **источнике паттерна** (`(?i)`) и флаги **API** могут дублироваться или конфликтовать — держи один источник правды. |
| 20 | |
| 21 | <!-- section:dotnet --> |
| 22 | ## .NET (`System.Text.RegularExpressions`) |
| 23 | |
| 24 | - Класс `Regex`; опции через `RegexOptions` (IgnoreCase, Multiline, Singleline, CultureInvariant, ECMAScript и др.). |
| 25 | - **Таймаут:** конструкторы и статические методы с `TimeSpan` — обязательны для пользовательского ввода паттернов. |
| 26 | - **Компиляция:** `RegexOptions.Compiled` — ускорение повторных запусков, цена на загрузку; не панацея при катастрофическом backtracking. |
| 27 | - Именованные группы: `(?<name>...)`; ссылки `\k<name>` в replacement через `${name}` в некоторых перегрузках. |
| 28 | |
| 29 | **Совет:** для парсинга форматов с вложенностью рассмотреть `GeneratedRegex`, span-перегрузки (.NET 7+) или специализированный парсер. |
| 30 | <!-- /section:dotnet --> |
| 31 | |
| 32 | <!-- section:javascript --> |
| 33 | ## JavaScript (ECMAScript RegExp) |
| 34 | |
| 35 | - Литерал `/pattern/flags` или конструктор `RegExp("pattern", "flags")` — **двойное** экранирование в строке. |
| 36 | - Флаги: `g`, `i`, `m`, `s` (dotAll), `u` (Unicode), `y` (sticky) — набор зависит от версии стандарта и движка. |
| 37 | - Lookbehind появился в современных движках; ограничения по длине lookbehind мягче, чем у «классического» ICU/PCRE в старых режимах, но проверяй цель. |
| 38 | |
| 39 | **Подводный камень:** методы строки и `RegExp` с флагом `g` хранят `lastIndex` — состояние между вызовами. |
| 40 | <!-- /section:javascript --> |
| 41 | |
| 42 | <!-- section:pcre-perl-style --> |
| 43 | ## PCRE / Perl-стиль |
| 44 | |
| 45 | - Богатый набор: условные паттерны, калли, рекурсия, атомарные подвыражения, владение — **не переносить** в минимальные движки. |
| 46 | - Флаги встроены в паттерн `(?i)` и т.д.; модификаторы `(?x)` free-spacing. |
| 47 | |
| 48 | Использование в проде: ограничивать подмножество фич, если паттерны пишут пользователи. |
| 49 | <!-- /section:pcre-perl-style --> |
| 50 | |
| 51 | <!-- section:java --> |
| 52 | ## Java `java.util.regex` |
| 53 | |
| 54 | - `Pattern` + `Matcher`; флаги `Pattern.CASE_INSENSITIVE`, `MULTILINE`, `DOTALL`, `UNICODE_CHARACTER_CLASS` и др. |
| 55 | - Поведение `\b` и `\w` сильно зависит от UNICODE-флагов. |
| 56 | |
| 57 | **Совет:** для сложных Unicode-сценариев явно включать Unicode-aware опции и тестировать на реальных данных. |
| 58 | <!-- /section:java --> |
| 59 | |
| 60 | <!-- section:workflow --> |
| 61 | ## Рабочий процесс (проверка паттерна) |
| 62 | |
| 63 | 1. Зафиксировать **примеры**: должны совпасть / не должны совпасть / граничные. |
| 64 | 2. Выписать **опции** (многострочность, Unicode, ignore case). |
| 65 | 3. Прогнать на **длинной** синтетике при пользовательских паттернах — ловля катастрофы. |
| 66 | 4. Включить **таймаут** или лимит в API, где возможно. |
| 67 | 5. Документировать **диалект** в комментарии к коду (одна строка: «PCRE 8.x / .NET / ES2024»). |
| 68 | |
| 69 | См. также дисциплину тестов и безопасности: `regex-playbook.md`. |
| 70 | |
| 71 | ## Связи |
| 72 | |
| 73 | - `kb-regex-syntax-features-v1.md` |
| 74 | - `kb-regex-engines-efficiency-v1.md` |
| 75 | - `index-knowledge-regex-cluster-v1.md` |
| 76 | |
| 77 | |