Regex PHP. Уменьшить количество шагов: ограничено фиксированной шириной - PullRequest
0 голосов
/ 07 января 2019

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

Я использую утверждения lokarround, позволяя знакам препинания и пробелам окружать теги.
Есть дополнительное осложнение, есть тип bb-кодов, которые представляют 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/

1 Ответ

0 голосов
/ 08 января 2019

Эмпирическое правило :

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

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

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

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

Что такое логика?

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

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

Смотрите демоверсию здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...