Javascript:使用'!'进行疯狂的布尔测试操作者

时间:2015-01-29 14:40:22

标签: javascript regex boolean

将以下函数调用输入到chrome控制台:

(function(regex, str){
    console.log(regex.test(str))
    console.log(!regex.test(str))
    console.log(! regex.test(str))
    console.log( !regex.test(str))
    console.log( ! regex.test(str))
})(new RegExp("new", "gmi"), "new")

我得到以下结果:

true
true
false
true
false

有人可以解释为什么第3和第5次测试会返回false吗? 为什么第一个和第二个都返回真实。

2 个答案:

答案 0 :(得分:10)

您包含“g”修饰符,因此正则表达式对象将保持匹配进度的状态。换句话说,每次通话都不一样。

您的第一个调用与字符串"new"匹配,正则表达式将位置更新为字符串的结尾。下一场比赛失败(因此您看到true的{​​{1}})。它失败,因为字符串“new”没有出现在字符串“new”的末尾。

现在我们已经运行了字符串的结尾,因此下一个测试将像第一个一样开始。它会再次匹配,因此!regexp.test(str)会将!变为true。之后的那个不匹配,之后的那个将重新开始并匹配。

请注意,测试中false周围的空格与行为完全无关。

编辑 - 尝试以下变体:

!

您会看到(function(regex, str){ console.log(regex.test(str) + " - " + regex.lastIndex) console.log(!regex.test(str) + " - " + regex.lastIndex) console.log(! regex.test(str) + " - " + regex.lastIndex) console.log( !regex.test(str) + " - " + regex.lastIndex) console.log( ! regex.test(str) + " - " + regex.lastIndex) })(new RegExp("new", "gmi"), "new") 属性在.lastIndex0之间切换。

我认为这个故事的寓意是“除非你真的知道你想要,否则不要使用3。”

答案 1 :(得分:3)

我会向你解释发生了什么。仔细阅读评论。它的形式为

regex.lastIndex, actual value, negated value

// code below

(function(regex, str){
    console.log(regex.test(str)) // 0, true, false
    console.log(!regex.test(str)) // 3, false, true => lastIndex set to 0
    console.log(! regex.test(str)) // 0, true, false
    console.log( !regex.test(str)) // 3, false, true => lastIndex set to 0
    console.log( ! regex.test(str)) // 0, true, false
})(new RegExp("new", "gmi"), "new")

MDN

  

如果lastIndex等于字符串的长度,如果是常规字符串   表达式与空字符串不匹配,那么常规   表达式不匹配输入,lastIndex重置为0.

因此,如果多次使用全局正则表达式,则lastIndex会更新,并决定从哪里开始匹配。