JavaScript正则表达式g的疑问

var reg = /^(https|http)?:\/\//g;
str = "https://www.baidu.com";
reg.test(str);

这个正则我是用来测试str是否是http://https://开头,但蛋疼的事发生了,reg.test(str)每次返回的结果是不一样的,一次true一次false,简直颠覆我三观。

有图为证:
图片描述

然后网上查了下,把g去了就好。可这就让我疑惑了,g只是全局匹配,在这怎么会影响结果呢,而且为什么是一次true一次false呢。

阅读 3.7k
5 个回答

谢邀!

虽然已经有最佳答案,但出于对正则的喜爱,还是忍不住要来说几句?

var reg = /^(https|http):\/\//g;
var str = "https://www.baidu.comhttps://www.baidu.com";
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));

以上是群主的true和false切换的代码,打印结果可以看到起始索引是在0,8之间切换。
为什么不是每次从0开始呢?不错,就是这个/g引起的。
若不加/g,则只返回第一个匹配,无论执行多少次均是如此;
若加入/g,则第一次返回第一个匹配,第二次返回第二个匹配,依次类推。
上述解释按理来说,应该是0,8,29...,可为什么是0,8呢?看看下面这段代码:

var reg = /(https|http):\/\//g;
var str = "https://www.baidu.comhttps://www.baidu.com";
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));
console.log( reg.lastIndex, reg.test(str));

是的,就是reg里^这个是起始标志在作怪了,第二次已经匹配不到了,索引置0。
其实,在测试是否存在这种功能里,/g是没啥意义的,解决方法有两种:

  1. 去掉/g

  2. 索引重置

var reg = /(https|http):\/\//g;
var str = "https://www.baidu.comhttps://www.baidu.com";
reg.lastIndex=0
console.log(reg.test(str));
reg.lastIndex=0
console.log(reg.test(str));
reg.lastIndex=0
console.log(reg.test(str));
reg.lastIndex=0
console.log(reg.test(str));
reg.lastIndex=0
console.log(reg.test(str));
reg.lastIndex=0
console.log(reg.test(str));

g 会记住上次test最后匹配的位置,下次会从那个位置开始查找~

lastIndex
使用正则变量全局匹配同一个字符串,并不都是从头开始。看一下上面的传送门。

改成这样/^(https|http)?:\/\//g.test(str)就可以了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题