У меня есть эти строки (проверка каждой строки отдельно):
adminUpdate
adminDeleteEx
adminEditXe
adminExclude
listWebsite
listEx
Теперь я хочу сопоставить все, что начинается с admin
но не заканчивается Ex
(без учета регистра)
Поэтому после применения регулярных выражений я должен соответствовать:
adminUpdate
adminEditXe
adminExclude
Мой текущий регулярное выражение /^admin[a-z]+(?!ex)$/gi
но это соответствует всему, что начинается с admin
Просто небольшое изменение:
/^admin[a-z]+(?<!ex)$/gi
^
Превратите свой взгляд в будущее.
Это довольно сложно объяснить в текущей форме. По сути, вам нужно достичь конца строки $
чтобы регулярное выражение соответствовало, и когда это произойдет, (?!ex)
находится в конце строки, поэтому впереди ничего не видно. Однако, поскольку мы находимся в конце строки, мы можем использовать оглядку (?<!ex)
проверить, заканчивается ли строка ex
или нет.
Поскольку осмотр имеет нулевую ширину, мы можем поменять местами (?<!ex)
а также $
без изменения значения (хотя это и меняет то, как движок ищет совпадающую строку):
/^admin[a-z]+$(?<!ex)/gi
Это нелогично, если вы пишете это так, но легче понять, к чему приводит мой аргумент.
Еще один способ взглянуть на это: из-за того, что (?!ex)
а также $
являются утверждением нулевой ширины, они проверяются в одной и той же позиции и находятся в конце строки $
подразумевает, что вы ничего не увидите впереди.
^(?!.*Ex$)admin.*$
Попробуйте это. См. Демо.
https://regex101.com/r/sH8aR8/23
$re = ""^(?!.*Ex$)admin.*$"m";
$str = "adminUpdate\nadminDeleteEx\nadminEditXe\nadminExclude\nlistWebsite\nlistEx";
preg_match_all($re, $str, $matches);