字符串中间的正则表达式反向匹配

4

我有这些字符串(每行分别检查):

adminUpdate
adminDeleteEx
adminEditXe
adminExclude
listWebsite
listEx

现在我想匹配以admin开头但不以Ex结尾的任何内容(不区分大小写)。
因此,在应用正则表达式后,我必须匹配:
adminUpdate
adminEditXe
adminExclude

我的当前正则表达式是 /^admin[a-z]+(?!ex)$/gi 但它匹配任何以 admin 开头的内容。

2个回答

8

仅仅是一个微小的变化:

/^admin[a-z]+(?<!ex)$/gi
               ^

将您的前瞻转化为后顾。
目前形式下很难解释。基本上,您需要到达字符串$的末尾才能匹配正则表达式,并且当它发生时,(?!ex)在字符串的末尾,因此它无法看到任何前面的内容。但是,由于我们已经到达字符串的末尾,我们可以使用后顾(?<!ex)来检查字符串是否以ex结尾。
由于环视是零宽度的,因此我们可以交换(?<!ex)$的位置而不改变含义(但它确实会改变引擎搜索匹配字符串的方式):
/^admin[a-z]+$(?<!ex)/gi

这种写法可能与直觉相反,但更容易看出我的论点。

另一种理解方法是: 由于(?!ex)$都是零宽断言,因此它们在同一位置进行检查,并且位于字符串末尾的$意味着您将不会看到任何前面的内容。


谢谢,它起作用了。你能解释为什么这里的前瞻不起作用吗? - Justinas
@Justinas:我添加了解释,但这是相当高级的解释。你可能想在regex101上使用正则表达式调试器功能来查看发生了什么。 - nhahtdh

3
^(?!.*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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接