发表于2015-09-08 22:21:52
有个很多年前我带过的同事来问我一个JS正则问题,大概就是正则第一次匹配A参数时,可以正常匹配,第二次匹配本应该能正常匹配的参数B时,却匹配失败。
我多次检测正则的写法确认其完全无误后,于是乎忍不住开始感兴趣起来。代码简化如下:
var r = new RegExp("^0|1$", "ig") console.log(r.test("0")) //true 匹配 console.log(r.test("1")) //false 不匹配
理论上,这二个表达式应该都能正常匹配,但是结果却出人意料。
在多次测试中,将二个表达式调换位置,有趣的现象出现了:
var r = new RegExp("^0|1$", "ig") console.log(r.test("1")) //true 匹配 console.log(r.test("0")) //false 不匹配
从这里看得出,匹配的结果,竟然跟位置有关。再稍稍改变代码如下:
span style="color: #0000FF;">var r = new RegExp("^0|1$", "ig") console.log(r.test("0")) //true 匹配 console.log(r.test("0")) //false 不匹配 console.log(r.test("0")) //true 匹配 console.log(r.test("0")) //false 不匹配 console.log(r.test("0")) //true 匹配 console.log(r.test("0")) //false 不匹配
只要是奇次均能匹配,偶次均无法匹配。而在测试中,去掉正则的全局匹配模式(g)则完全正常。
经过一番搜索,终于找到答案:
在JS的正则表达式中,全局匹配模式下,test每次匹配会变换游标,不会重新初化,而是会接着上次结束的位置开始。第一次test(0)前,游标位置是0,所以能 正则匹配表达式,第一次匹配结束后,第二次匹配结束,游标位置是1,故第二次匹配失败.第三次开始匹配时,游标又回到了0,第三次匹配成功,依此循环……
我们可以使用 r.lastIndex 查看游标位置,同样,我们在上述代码中,加上游位代码,可以看出问题所在:
var r = new RegExp("^0|1$", "ig") console.log(r.lastIndex) //0 console.log(r.test("0")) //true 匹配 console.log(r.lastIndex) //1 console.log(r.test("0")) //false 不匹配 console.log(r.lastIndex) //0 console.log(r.test("0")) //true 匹配 console.log(r.lastIndex) //1 console.log(r.test("0")) //false 不匹配 console.log(r.lastIndex) //0 console.log(r.test("0")) //true 匹配 console.log(r.lastIndex) //1 console.log(r.test("0")) //false 不匹配结论:在JS正则表达式中,使用test时,切记不要使用全局模式。正确代码如下:
var r = new RegExp("^0|1$", "i") console.log(r.test("0")) //true 匹配 console.log(r.test("0")) //true 匹配原创作品,转载请注明 作者:翅膀的初衷 出处:www.jiniannet.com