我以为我理解正则表达式运算符是如何工作的,但现在我真的很困惑。 在简化示例中,我有两个字符串:
mail.wow.no-1.com
mail.ololo.wow.com
我想匹配第一个,而不是第二个。 我正在写这样的正则表达式(简化版):
^mail\.(.*)(?!\.wow\.com)$
当我在这两个例子的JS方法测试中运行时,它只返回true(在sublime 2正则表达式搜索中突出显示两个字符串,这意味着两个字符串匹配)
我知道我可以制作反向正则表达式,它将匹配第二个并根据此制作逻辑,但我只是想了解正则表达式中的(?!)
如何工作以及我做错了什么。
感谢。
答案 0 :(得分:8)
您需要在前瞻中找到.*
(并将其移到前瞻之外的.*
前面):
^mail(?!.*\.wow\.com)\.(.*)$
否则,您的前瞻只会检查字符串的末尾。显然,在字符串的末尾,永远不会有.wow.com
。您现在也可以将前瞻移动到模式的开头:
^(?!.*\.wow\.com)mail\.(.*)$
这最后一个变体的效率稍差,但如果影响整个字符串的前瞻一切都在模式的开头,我发现模式更容易阅读。
答案 1 :(得分:3)
答案 2 :(得分:3)
你想要的是
^mail\.(?!.*\.wow\.com$).*$
正如其他人所说,(?!)是一个负零宽度前瞻断言;它与任意数量的字符都不匹配,但会看到下一个字符,并确保它们与括号中包含的字符不匹配。
Javascript从Perl复制了正则表达式语法;这些通常称为PCRE,或Perl兼容的正则表达式;然而,Javascript只有前瞻性,即他们从这一点看到了未来; Perl也具有负零宽度后视,它可以像原始示例一样工作,在这种情况下更容易
# this is how it could be done in Perl
^mail\..*(?<!\.wow\.com)$
然而,Javascript选择不支持lookbehinds。
答案 3 :(得分:1)
对此网址的检查是它查找“邮件”。然后尽可能多的字符,然后检查是否存在(即字符串的结尾)和屏幕的结尾,如果“.wow.com”存在。
^mail\.(.*)(?!\.wow\.com)$
相反,请对其进行重新排序,以便检查“.wow.com”是否位于“mail”之后。
^mail\.(?!.*\.wow\.com)(.*)$