Javascript 正则表达式中的(?!)操作符是如何工作的?
我原以为我了解正则表达式操作符是如何工作的,但现在我真的很困惑。 在简化的示例中,我有两个字符串:Javascript 正则表达式中的(?!)操作符是如何工作的?,javascript,regex,Javascript,Regex,我原以为我了解正则表达式操作符是如何工作的,但现在我真的很困惑。 在简化的示例中,我有两个字符串: mail.wow.no-1.com mail.ololo.wow.com 我想匹配第一个,而不是第二个。 我写的regex(简化版)是这样的: ^mail\.(.*)(?!\.wow\.com)$ 当我在这两个示例上运行JS方法测试时,它只返回true(在sublime 2中,正则表达式搜索突出显示两个字符串,这意味着两个字符串都匹配) 我知道我可以制作反向正则表达式,这将匹配秒数并根据这一点
mail.wow.no-1.com
mail.ololo.wow.com
我想匹配第一个,而不是第二个。
我写的regex(简化版)是这样的:
^mail\.(.*)(?!\.wow\.com)$
当我在这两个示例上运行JS方法测试时,它只返回true(在sublime 2中,正则表达式搜索突出显示两个字符串,这意味着两个字符串都匹配)
我知道我可以制作反向正则表达式,这将匹配秒数并根据这一点生成逻辑,但我只想了解正则表达式中的(?!)
是如何工作的,我做错了什么
谢谢。这是一个好主意。这是一个消极的展望
它所说的:在这个位置上——以下情况不可能出现
因此,例如,
(?!q)
意味着字母q
现在不能跟在后面。您需要一个*
在前视框内(并将其移动到前视框外的*
前面):
否则,前瞻只在字符串的末尾进行检查。显然,在字符串的末尾,永远不会有.wow.com
。您现在也可以将前瞻移到模式的开头:
^(?!.*\.wow\.com)mail\.(.*)$
最后一个变体的效率稍低,但我发现如果影响整个字符串的lookahead都位于模式的开头,那么模式更容易阅读。对这个url的检查是它查找“邮件”。然后尽可能多的字符,然后检查它们之间是否存在差异(即字符串的结尾)如果存在“.wow.com”,则显示屏幕的结尾 相反,对它重新排序,以便它检查“.wow.com”是否在“mail”之后 你想要的是
^mail\.(?!.*\.wow\.com$).*$
正如其他人所说,(?!)是一个负的零宽度前瞻断言;它不匹配任何数量的字符,但会查看下一个字符,并确保它们与括号中包含的内容不匹配
Javascript从Perl复制了正则表达式语法;这些通常被称为PCRE或Perl兼容的正则表达式;然而,Javascript只有外观,也就是说,他们从这一点看未来;Perl还具有负零宽度外观,这将与原始示例一样工作,在本例中更简单
# this is how it could be done in Perl
^mail\..*(?<!\.wow\.com)$
#这是如何在Perl中实现的
^邮寄\..*(?
然而,Javascript选择不支持lookbehinds。我通常认为负面lookbehind更容易理解,但不幸的是,这是Javascript:)此外,在尝试理解复杂的正则表达式时,您可能会发现它很有用
^mail\.(?!.*\.wow\.com)(.*)$
^mail\.(?!.*\.wow\.com$).*$
# this is how it could be done in Perl
^mail\..*(?<!\.wow\.com)$