繁体   English   中英

正则表达式中的(?!)运算符如何工作?

[英]How does (?!) operator in regex work?

我以为我理解正则表达式运算符是如何工作的,但现在我真的很困惑。 在简化示例中,我有两个字符串:

mail.wow.no-1.com
mail.ololo.wow.com

我想匹配第一个,而不是第二个。 我正在写这样的正则表达式(简化版):

^mail\.(.*)(?!\.wow\.com)$

当我在这两个例子中运行JS方法测试时,它只返回true(在崇高的2正则表达式搜索中突出显示两个字符串,这意味着两个字符串匹配)

我知道我可以制作反向正则表达式,它将匹配第二个并根据这个制作逻辑,但我只是想了解正则表达式中的(?!)是如何工作的以及我做错了什么。

谢谢。

在前瞻中你需要一个.* (并在前瞻之外的.*移动它):

^mail(?!.*\.wow\.com)\.(.*)$

否则,您的前瞻只会检查字符串的末尾。 显然,在字符串的末尾,永远不会有.wow.com 您现在也可以将前瞻移动到模式的开头:

^(?!.*\.wow\.com)mail\.(.*)$

工作演示。

最后一个变体的效率稍差,但如果影响整个字符串的前瞻一切都在模式的开头,我发现模式更容易阅读。

这是零宽度断言 这是一个负面的展望。

它说的是:在这个位置 - 以下不可能来。

因此,例如(?!q)意味着,字母q现在不能遵循。

你想要的是什么

^mail\.(?!.*\.wow\.com$).*$

正如其他人所说,(?!)是一个负零宽度前瞻断言; 它与任意数量的字符都不匹配,但会看到下一个字符,并确保它们与括号中包含的字符不匹配。

Javascript从Perl复制了正则表达式语法; 这些通常称为PCRE,或Perl兼容的正则表达式; 然而,Javascript只有前瞻性,即他们从这一点看到了未来; Perl也具有负零宽度后视,这将像您的原始示例一样工作,在这种情况下更容易

# this is how it could be done in Perl
^mail\..*(?<!\.wow\.com)$

但是,Javascript选择不支持lookbehinds。

对这个网址的检查是它寻找“邮件”。 然后尽可能多的字符,然后检查是否存在“.wow.com”之间(即字符串的结尾)和屏幕的结尾。

^mail\.(.*)(?!\.wow\.com)$

而是重新排序,以便检查“.wow.com”是否在“邮件”之后。

^mail\.(?!.*\.wow\.com)(.*)$

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM