在全局模式(global)下使用正则表达式,有一些需要特别注意的地方,先来看一段有意思的代码:
- <script>
- var reg = /\d/g;
- var str = "1";
- alert(reg.test(str)); //应该弹出true
- alert(reg.test(str)); //应该弹什么呢?
- alert(reg.test(str)); //这次呢?
- </script>
直观感觉它应该三次都弹出true,但实际上运行一下,三次的结果分别是:true / false / true。这是为什么呢?
原因在于使用正则表达式的全局模式时,在正则实例上调用test方法,会更改其lastIndex属性,而此属性指示了匹配的开始位置,所以第一次调用test时lastIndex=0,能匹配上,匹配完成后lastIndex变为1,第二次调用test时lastIndex=1,就匹配不上了,此时lastIndex回0,第三次调test时lastIndex=0,所以又能匹配上了。
需要注意的是,将正则实例作为参数传入时,不会影响lastIndex属性。
进一步深入一下,不同浏览器上还会有细微的差别:
在IE下: lastIndex 属性会被 RegExp 实例的 exec 、test 方法,以及String实例的match、replace、split、search 方法修改; 在Firefox、Opera、Safari、Chrome下: lastIndex 属性会被 RegExp 实例的 exec、test 方法修改,但不会被 String 实例的各个方法修改; |
来看几个例子加深一下理解:
1、创建一个正则实例并指明了global全局模式,然后两次调用exec方法。
- <script>
- var reg = /\d/g;
- var str = "1";
- alert( reg.exec(str) ); //结果是1
- alert( reg.exec(str) ); //结果居然是null!! 没想到吧!
- alert( reg.exec(str) ); //这次又是1了
- </script>
2、创建一个正则实例并指明了global全局模式,然后两次作为String.match方法的参数被调用。
- <script>
- var reg = /\d/g;
- var str = "1";
- alert( str.match(reg) ); //结果是1
- alert( str.match(reg) ); //结果也是1
- </script>
3、创建一个正则实例并指明了global全局模式,然后两次作为String.search方法的参数被调用。
- <script>
- var reg = /\d/g;
- var str = "abc1";
- alert( str.search(reg) ); //结果是3
- alert( str.search(reg) ); //结果也是3
- </script>
4、创建一个正则实例并指明了global全局模式,然后两次作为String.replace方法的参数被调用。
- <script>
- var reg = /\d/g;
- var str = "abc1";
- alert( str.replace(reg,"") ); //结果是abc
- alert( str.replace(reg,"") ); //结果也是abc
- </script>
5、混合调用一下。
- <script>
- var reg = /\d/g;
- var str = "abc1";
- alert( str.replace(reg,"") ); //结果是abc
- alert( reg.test(str) ); //IE:false //others: true
- var reg2 = /\d/g;
- var str = "abc1";
- alert( str.search(reg2) ); //结果是3
- alert( reg2.test(str) ); //IE:false //others: true
- var reg3 = /\d/g;
- var str = "abc1";
- alert( str.split(reg3) ); //结果是abc
- alert( reg3.test(str) ); //IE:false //others:true
- var reg4 = /\d/g;
- var str = "abc1";
- alert( str.match(reg4) ); //结果是1
- alert( reg4.test(str) ); //IE:false //others:true
- </script>
6、进一步看看IE与其它浏览器的不同。
- <script>
- var reg = /\d*/g; //注意这里跟上面的示例的不同
- var str = "1";
- alert( reg.lastIndex ); //IE: 0 //others: 0
- alert( reg.test(str) ); //IE: true //others: true
- alert( reg.lastIndex ); //IE: 1 //others: 1
- alert( reg.test(str) ); //IE: true //others: true
- alert( reg.lastIndex ); //IE: 2 //others: 1
- alert( reg.test(str) ); //IE: false //others: true
- alert( reg.lastIndex ); //IE: 0 //others: 1
- alert( reg.test(str) ); //IE: true //others: true
- alert( reg.lastIndex ); //IE: 1 //others: 1
- alert( reg.test(str) ); //IE: true //others: true
- alert( reg.lastIndex ); //IE: 2 //others: 1
- alert( reg.test(str) ); //IE: false //others: true
- alert( reg.lastIndex ); //IE: 0 //others: 1
- alert( reg.test(str) ); //IE: true //others: true
- </script>
有点小复杂,注意这可不是正则表达式的BUG,各位在使用时要多加留心。