Безопасные шаблоны автоответов
Kizora поддерживает ограниченный язык шаблонов — не полный PCRE и не то, что понимает Python. Ограничения не косметические: шаблон вводит администратор чужого сервера, а проверка вызывается на каждом сообщении.
Что поддерживается
| Конструкция | Значение | Пример |
|---|---|---|
| Обычный текст | Совпадает буквально | привет |
. | Любой символ, кроме перевода строки | код. |
[...] | Один символ из набора | [0-9], [а-я] |
[^...] | Один символ не из набора | [^0-9] |
\d \w \s | Цифра, буква или цифра, пробел | \d\d |
\D \W \S | Их отрицания | \S+ |
* + ? | Повтор: ноль и больше, один и больше, ноль или один | скидк\w* |
{n} {n,m} {n,} | Точный и ограниченный повтор, до 20 | \d{3} |
^ $ | Начало и конец текста | ^привет$ |
\B | Граница слова и её отрицание | скидка |
| Вертикальная черта | Варианты, до 4 (см. пример ниже) | — |
(?: ... ) | Группировка без запоминания, до 3 групп | см. пример ниже |
\. \? и т. п. | Экранирование спецсимвола | кто\? |
Поиск по умолчанию не различает регистр.
Что не поддерживается
| Конструкция | Почему |
|---|---|
( ... ) с запоминанием | Не нужны: результат — «нашлось или нет», без границ совпадения |
Обратные ссылки | Конечным автоматом их выразить нельзя |
Заглядывания (?= (?! (?<= (?<! | То же самое |
| Вложенные группы | Ограничение читаемости шаблона |
| Квантификатор после группы | Повторить можно один символ, класс или . |
Пределы
| Ограничение | Значение |
|---|---|
| Длина шаблона | 200 символов |
Групп (?: ... ) | 3 |
| Вариантов через вертикальную черту в группе | 4 |
Верхняя граница {n,m} | 20 |
Безграничных повторов (*, +, {n,}) | 2 |
| Просматривается символов сообщения | 1000 |
Шаблон, который не влезает в бюджет, отвергается с понятной причиной, а не принимается на удачу.
Почему так
Обычный движок регулярных выражений ищет с возвратами. Шаблон вида a{0,20} семь раз подряд плюс b на шестидесяти символах считается около девяти секунд — и это законная по отдельности конструкция. Перечислять опасные формы бесполезно: список закрывает те, о которых вспомнили.
Поэтому Kizora строит из шаблона конечный автомат и ищет без возвратов. Время работы — линейное от длины текста и не зависит от формы шаблона. Тот же шаблон, который вешал бы обычный движок, считается за миллисекунды.
Проверенные примеры
Принимаются:
привет
^привет$
привет.*
[0-9]
\d{3}-\d{2}
скидк\w*
промо.{0,10}код
(?:ку|при)вет
\S+@\S+
привет|здравствуйтеОтклоняются:
(привет) — скобки с запоминанием
(a+)+ — то же самое
(?=x)y — заглядывание
(\w+) — обратная ссылка
.*.*.* — больше двух безграничных повторов
(?:раз|два|три|четыре|пять) — больше четырёх вариантовКогда шаблон не нужен
Пять условий из шести не требуют шаблона вовсе: точное совпадение, «содержит», «начинается с», «заканчивается на» и «упомянули бота». Шаблон стоит брать, только когда остальные не подходят, — он сложнее в чтении и в отладке.