Начните бесплатный 3-дневный пробный период
Зарегистрируйтесь и попробуйте все премиум-функции бесплатно.
*Только для новых пользователей. Один пробный период на пользователя.


Чтобы писать регулярные выражения с ИИ, задайте движок и контракт, затем запустите тесты. Следуйте процессу работы с ИИ; решение даёт реальный движок.
Ключевые выводы
- Укажите среду выполнения, движок, версию, API, флаги и семантику полного совпадения или поиска.
- До синтаксиса сформулируйте разрешающий контракт.
- Проверьте допустимые, недопустимые, граничные, Unicode, многострочные и враждебные входы.
- Разделяйте синтаксис регулярного выражения, экранирование строки языка и командной оболочки.
- Проверяйте группы и замену, а не только true/false.
- Ограничьте вход и ищите катастрофический возврат с перебором и ReDoS.
- Выберите синтаксический анализатор или обычные строки, если выражение стало непрозрачным.
Регулярное выражение не исправит неоднозначное требование. Запишите, что разрешено и запрещено, требуется ли совпадение всей строки и как дальнейший код будет использовать группы.
Для синтетического ключа заявки контракт может выглядеть так:
| Поле | Решение |
|---|---|
| Допустимая форма | Две заглавные ASCII-буквы, дефис, четыре цифры |
| Вся строка | Да, без текста до и после |
| Длина | Ровно 7 символов |
| Допустимые примеры | AB-0042, ZX-9000 |
| Недопустимые | ab-0042, AB 0042, AB-42, XAB-0042Y |
| Группы | Префикс и числовая часть |
| Источник | Недоверенное поле формы |
| Лимит до сопоставления | 64 символа |
OWASP советует определить разрешённый набор символов и минимальную и максимальную длину.[4]Если область позволяет, используйте узкий список разрешённых значений. Не просите «идеальное регулярное выражение для любого идентификатора» — задайте грамматику и владельца политики.
Разделяйте валидацию и извлечение. Шаблон, который ищет ключ в абзаце, не обязан валидировать всё поле. Клиентская проверка для удобства не заменяет серверную.
JavaScript, Python, Java, .NET, Rust, функции базы, командные инструменты и редакторы поддерживают разные диалекты. Даже общий синтаксис может иметь разные API и значения по умолчанию.
Запишите:
| Поле | Пример |
|---|---|
| Язык и среда выполнения | Python 3.14 |
| Движок | Стандартный модуль re |
| API | re.fullmatch |
| Представление | Необработанный строковый литерал |
| Флаги | Нет |
| Unicode-политика | Только ASCII-буквы |
| Группы | Именованные prefix, number |
| Замена | Не используется |
MDN показывает, что флаги JavaScript меняют глобальный поиск, регистр, многострочные якоря, совпадение точки с переводом строки и Unicode.[1]У Python re свои функции, флаги и синтаксис обратных ссылок при замене.[2]Успех в онлайн-тестере ничего не доказывает без того же движка и настроек.
Полное совпадение, совпадение префикса и поиск — разные контракты. В JavaScript для полной строки часто применяют ^ и $, а Python выражает намерение через fullmatch. Всё равно проверяйте перевод строки и многострочный режим, а не переносите предположения между движками.
Примеры должны быть понятны владельцу требования без знания регулярных выражений. Начните с требований, затем добавьте границы и почти подходящие значения.
| Случай | Вход | Ожидание | Причина |
|---|---|---|---|
P-01 | AB-0042 | Совпадение; AB, 0042 | Обычный допустимый ввод |
P-02 | ZX-9000 | Совпадение; ZX, 9000 | Другие допустимые значения |
N-01 | ab-0042 | Нет | Нижний регистр запрещён |
N-02 | AB 0042 | Нет | Неверный разделитель |
N-03 | AB-42 | Нет | Мало цифр |
N-04 | XAB-0042Y | Нет | Лишний текст |
B-01 | Пустая строка | Нет | Нижняя граница |
B-02 | 64-символьный отказ | Отказ в бюджете | Максимальный вход |
A-01 | Длинный повтор и ! | Отказ в бюджете | Проверка возврата с перебором |
Не позволяйте ИИ одновременно придумать правило и все ожидаемые ответы. Оракул приходит из требования, протокола, стандарта или политики. Процесс генерации тестов расширит матрицу, но метки утверждает владелец.
Добавьте пустое значение, длину на один меньше и больше каждой границы, повторные разделители, переводы строк, похожие Unicode-символы, пробелы, NULL в месте вызова и очень длинные отказы. Если группы используются далее, задайте точные значения.
Дайте модели контракт и синтетическую таблицу, а не закрытые рабочие примеры.
Цель: Python 3.14, стандартный re, re.fullmatch и raw string.
Контракт: две заглавные ASCII-буквы, буквальный дефис, четыре цифры.
Верни одно выражение с именованными группами `prefix` и `number`.
Объясни каждый элемент, перечисли предположения и не расширяй алфавит.
Создай исполняемые тесты для данных случаев, не добавляя требований.
Неуверенность в движке или экранировании помечай [VERIFY].
Кандидат:
pattern = r"(?P<prefix>[A-Z]{2})-(?P<number>[0-9]{4})"
В этом синтетическом примере re.fullmatch устраняет необходимость явных якорей. Это вывод для конкретного API, а не универсальный стиль. Попросите объяснить каждую группу, квантификатор, класс, альтернативу, проверку окружения и флаг. Удалите синтаксис без роли в контракте.
Часто регулярное выражение правильно, но неправильно завёрнуто в строку. Отдельно фиксируйте:
Необработанная строка Python может быть читабельнее, но соблюдает правила Python. В JavaScript литерал и new RegExp("...") требуют разного экранирования. Строка замены имеет ещё одну грамматику; Python документирует ссылки \g<name> и \g<number>.[2]
Сохраните исходный литерал, фактическое значение выражения и вызов. При необходимости тестируйте буквальный слеш, кавычку, перевод строки и замену. Не исправляйте экранирование методом случайных изменений без указания слоя.
Исполните весь корпус в настоящей системе тестирования проекта:
import re
PATTERN = re.compile(r"(?P<prefix>[A-Z]{2})-(?P<number>[0-9]{4})")
def parse_ticket(value: str):
if len(value) > 64:
return None
return PATTERN.fullmatch(value)
assert parse_ticket("AB-0042").groupdict() == {
"prefix": "AB",
"number": "0042",
}
assert parse_ticket("ab-0042") is None
assert parse_ticket("XAB-0042Y") is None
Лимит длины ограничивает работу до сопоставления; число 64 относится только к синтетическому контракту. В реальном приложении до движка проверяются тип и значение NULL. Серверные тесты нужны даже при браузерной проверке.
Для замены сравнивайте полный вывод и нетронутые части. Для глобального режима или API с состоянием проверяйте повторные вызовы и пустые совпадения. Для нескольких строк охватите варианты перевода и выбранный многострочный режим.
Класс символов скрывает политику. Соответствует ли \d только ASCII или более широкому Unicode в данном режиме? Что делает режим без учёта регистра за пределами A-Z? Включает ли точка перевод строки? Сохраняет ли глобальный режим состояние?
| Измерение | Вопрос | Свидетельство |
|---|---|---|
| Unicode | Какие письменности и формы нормализации допустимы? | Утверждённый корпус |
| Пробелы | Различаются ли пробел, табуляция и перевод строки? | Граничные тесты |
| Флаги | Зачем нужен каждый флаг? | Настройка среды выполнения |
| Группы | Стабильны ли имена и необязательные значения? | Точные проверки |
| Замена | Что происходит с отсутствующей группой? | Ожидаемые результаты |
| Итерация | Может ли пустое совпадение остановить цикл? | Тест цикла |
Не используйте выражение только для ASCII при проверке международных имён и не принимайте весь Unicode в протоколе, который требует ASCII. Политику задаёт владелец, модель лишь реализует запись.
Некоторые движки с возвратом и перебором резко замедляются на специально созданном вводе. OWASP выделяет повторение внутри повторяемой группы и перекрывающиеся альтернативы, приводя (a+)+$ как пример.[3]Поэтому нужны длинные враждебные несовпадения.
Ищите неоднозначные вложенные квантификаторы, перекрывающиеся альтернативы, обратные ссылки на неограниченном тексте и пользовательские части выражения. Затем:
Не объявляйте универсальную безопасность «за 10 мс». Бюджет определяется приложением и средой, а заверение модели о линейности не является ни измерением, ни доказательством.
Никогда не вставляйте сырой пользовательский ввод в регулярное выражение. Если нужен буквальный поиск, используйте функцию экранирования движка и всё равно ограничивайте длину ввода. Если пользователям намеренно разрешено задавать шаблоны, считайте это отдельной функцией высокого риска с изоляцией движка, ограничением ресурсов и проверкой безопасности.
Выбирайте строки, синтаксический анализатор или библиотеку предметной области для вложенной, контекстной или стандартизованной грамматики. HTML, языки программирования, сложные адреса и меняющиеся правила часто не должны принадлежать одному выражению.
Остановитесь, если:
Конкретное несовпадение разбирайте через отладку с ИИ, а окружающий сгенерированный код — через проверку до запуска.
Один пример не задаёт все допустимые и запрещённые значения. Нужны контракт, положительные, отрицательные, граничные и враждебные случаи в целевом движке.
В тестере могут отличаться движок, флаги, API или слой экранирования. Воспроизведите фактическое значение выражения в среде выполнения и место вызова.
Выберите идиому целевого движка, точно выражающую совпадение всей строки. Проверьте новые строки и многострочный режим.
Первое задаёт синтаксис выражения, второе — хранение этого выражения в коде. JSON, YAML, шаблон и командная оболочка добавляют слои.
\d равно [0-9]?Нет. В некоторых движках и режимах \d включает более широкий набор Unicode-цифр. Выберите класс по политике и протестируйте символы.
Изучите структуру, ограничьте вход, добавьте длинные несовпадения и измерьте реальный движок под контролем ресурсов. Не доверяйте одной оценке модели.
Не вставляйте его как синтаксис. Для буквального поиска используйте функцию экранирования; пользовательские выражения требуют отдельной изолированной функции.
Когда данные вложены, контекстны, стандартизованы или небольшое выражение уже невозможно объяснить. Поддерживаемость является частью корректности.
Sources checked 4 сентября 2026 г.
Зарегистрируйтесь и попробуйте все премиум-функции бесплатно.
*Только для новых пользователей. Один пробный период на пользователя.





