当正则表达式开了挂,就会多一个g的修饰符,用于表示全局匹配。然而这个表达式却不仅仅是多了个g这么简单,它的方法也会发生改变。由于之前不是太了解,今天好好捋一下,且听我细细道来。
正则表达式的方法和属性
正则表达式的属性基本上与正则表达式的字面量的组成部分一一对应:
正则有两大方法:test
和exec
,其中exec尤其强大,但此处只谈稍微弱一点的test。
test方法在两种模式下的异同
下面就以/foo/和/foo/g来说明。相关代码如下:
var re1 = /foo/, re2 = /foo/g;
re1.test('foobar') // true
re1.test('foobar') // true
re2.test('foobar') // true
re2.test('foobar') // false
为啥多了g之后,就会一次成功,一次失败呢?因为加上g之后正则会对字符串进行全局匹配。也就是说,当正则表达式第一次匹配成功之后,如果没有匹配到字符串末尾,带g的正则表达式会继续匹配下去,直到字符串末尾;而不带g的正则表达式在首次匹配成功之后,就会从头开始匹配。
一个不恰当的比喻是把正则比做👮,从一堆字符串中找小偷,如果正则表达式不带g,找到了返回true就结束;带g,即使找到了要找的字符串返回了true,再次调用时会继续寻找,看还有没有别的小偷。有点一查到底,绝不放过的意思。这一点可以从正则表达式的一个属性--lastIndex说明。请看代码:
var re1 = /foo/, re2 = /foo/g;
re1.test('foobar') //true
re1.lastIndex //0
re1.test('foobar') //true
re1.lastIndex //0
re2.test('foobar') //true
re2.lastIndex //3 字符串(0-2)匹配成功,下次从3开始匹配
re2.test('foobar') //false 匹配到最后都没找到
re2.lastIndex //0 下次从0开始匹配。
看到这里,结合注释,我想我们应该知道正则的匹配规则了。那么接下来考虑下面的问题,正则会记录匹配的位置,但是会不会记住匹配的字符串呢?
re2.test('foobar') //true
re2.test('fofoobar') //false
第二个匹配是false,可见正则只认index,不认字符串,典型的认钱不认人。即使你换了字符串,正则还是从lastIndex的地方开始匹配,所以这就解释了为什么匹配第二个字符串也是false。(完)
cnblogs-md-editor编辑器,用Markdown写博客就用它