JavaScript中的Regexp test方法表现奇怪

5

我一直在尝试使用正则表达式评估字符串,但是当我多次测试正则表达式时,发现了奇怪的行为。test方法会在true和false之间交替。 请查看此CodePen --> http://codepen.io/gpincheiraa/pen/BoXrEz?editors=001

var emailRegex = /^([a-zA-Z0-9_\.\-]){0,100}\@(([a-zA-Z0-9\-]){0,100}\.)+([a-zA-Z0-9]{2,4})+$/,
  phoneChileanRegex = /^\+56\S*\s*9\S*\s*\d{8}(?!\@\w+)/g,
   number = "+56982249953";

if(!number.match(phoneChileanRegex)  && !number.match(emailRegex) ) {
  console.log("it's not a phone number or email address");
}

//Weird Behaviour
console.log(phoneChileanRegex.test(number)); --> true
console.log(phoneChileanRegex.test(number)); --> false

2
这是由于 g 标志引起的,请查看 CodePen - Tushar
2个回答

12
MDN文档中得知:
exec()(或与其结合使用)一样,多次在同一全局正则表达式实例上调用test()将超越前一个匹配。
因此,第二次调用该方法时,它将在第一次匹配后查找匹配项,即在+56982249953之后。由于模式锚定到字符串的开头(^),且没有剩余字符,所以返回false
为了使这个方法工作,你需要移除g修饰符。

7
那是因为像许多RegExp方法一样,test方法在使用g标志时尝试在同一字符串中查找多个匹配项。为此,它会在RegExp的lastIndex属性中跟踪应该从哪个位置开始搜索。如果您不需要查找多个匹配项,请不要使用g标志。如果您想使用它,请记得在要测试新字符串时将regex.lastIndex设置为0。 在MDN上阅读有关lastIndex的更多信息

非常恰当的答案。我通过在第一个console.log之后放置断点并检查phoneChileanRegex.lastIndex发现了这一点,它显示为12,这意味着由于g标志而跟踪了位置。 - NiRUS
谢谢!我终于明白了使用.test方法时发生了什么。通常在使用String.replace方法时,我会使用g标志,但我不知道在Regexp.test方法中会出现这种行为。 - Gonzalo Pincheira Arancibia

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