Regex PHP. Уменьшить количество шагов: ограничено фиксированной шириной

У меня есть регулярное выражение, которое будет использоваться для соответствия тегам @users.

Я использую утверждения lokarround, позволяя пунктуации и пробелам окружать теги.
Есть дополнительное осложнение, есть тип bbcodes, которые представляют html.
У меня есть два типа BB-коды, встроенные (^B смелый ^b) и блоки (^C центр ^c).
Встроенные должны быть переданы через, чтобы добраться до предыдущего или следующего символа.
И блоки могут окружать тег, как пунктуация.

Я сделал регулярное выражение, которое работает. То, что я хочу сделать сейчас, это уменьшить количество шагов, которые он делает для каждого персонажа, который не будет совпадать.
Сначала я думал, что мог бы сделать регулярное выражение, которое будет просто искать @и когда он будет найден, он начнет смотреть на обходные пути, которые работают без встроенных bb-кодов, но поскольку просмотр за пределами не может быть количественно измерим, это сложнее, так как я не могу добавить ((\^[BIUbiu])++)* внутри, производя гораздо больше шагов.

Как я могу сделать свое регулярное выражение более эффективным с меньшим количеством шагов?

Вот его упрощенная версия, в ссылке Regex101 есть полное регулярное выражение.

(?<=[,\.:=\^ ]|\^[CJLcjl])((\^[BIUbiu])++)*@([A-Za-z0-9\-_]{2,25})((\^[BIUbiu])++)*(?=[,\.:=\^ ]|\^[CJLcjl])

https://regex101.com/r/lTPUOf/4/

2

Решение

Правило большого пальца:

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

Цитата изначально исходит из этого ответа. Следующее регулярное выражение значительно уменьшает шаги из-за левой стороны самого внешнего чередования, от ~ 20000 до ~ 900:

(?:[^@^]++|[@^]{2,}+)(*SKIP)(*F)
|
(?<=([HUGE-CHARACTER-CLASS])|\^[cjleqrd])
(\^[34biu78])*+@([a-z\d][\w-.]{0,25}[a-z\d])(\^[34biu78])*+(?=(?1))

На самом деле меня не волнует количество шагов, о которых сообщает regex101, потому что это не может быть правдой в вашей среде, и неясно, являются ли некоторые шаги реальными или нет, или какие шаги пропущены. Но в этом случае, поскольку логика регулярных выражений ясна, а разница велика, это имеет смысл.

В чем логика?

Сначала мы пытаемся сопоставить то, что, вероятно, вообще нежелательно, выбрасываем это и ищем части, которые могут соответствовать нашему шаблону. [^@^]++ соответствует до @ или же ^ символы (нужные символы) и [@^]{2,}+ препятствует тому, чтобы двигатель предпринял дополнительные шаги прежде, чем обнаружить, что это никуда не идет. Таким образом, мы делаем это, чтобы потерпеть неудачу как можно скорее.

Ты можешь использовать i флаг вместо определения прописных букв (это может оказать небольшое влияние).

Увидеть живое демо здесь

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]