正则 reg 中 match 和 exec 异同
match
是字符串方法,写法为:str.match(reg)
exec
是正则表达式方法,写法为:reg.exec(str)
match
和 exec
在匹配成功时返回的都是数组,在没有匹配上时返回的都是 null
。
当不使用全局匹配时,两者的匹配效果是一样的,仅返回第一次匹配成功的结果.(包括分组内容,匹配第一次) 如:
var str = 'abbb34eftab0modabbbbb6'
var reg = /a(b)+(\d+)/i
var matchArr = str.match(reg)
var execArr = reg.exec(str)
console.log(matchArr)
console.log(execArr)
// ['abbb34', 'b', '34', index: 0, input: 'abbb34eftab0modabbbbb6', groups: undefined]
2
3
4
5
6
7
使用全局匹配 /g
时,exec
的执行结果不受影响。但是 match
会返回全局匹配的结果,将不再有分组匹配信息和索引等值。如:
var str = 'abbb34eftab0modabbbbb6'
var reg = /a(b)+(\d+)/ig
var matchArr = str.match(reg)
var execArr = reg.exec(str)
console.log(matchArr)
// ['abbb34', 'ab0', 'abbbbb6']
console.log(execArr)
// ['abbb34', 'b', '34', index: 0, input: 'abbb34eftab0modabbbbb6', groups: undefined]
2
3
4
5
6
7
8
当再次调用 exec
时,会往后进行搜索:
var execArr2 = reg.exec(str)
console.log(execArr2)
// ['ab0', 'b', '0', index: 9, input: 'abbb34eftab0modabbbbb6', groups: undefined]
var execArr3 = reg.exec(str)
console.log(execArr3)
// ['abbbbb6', 'b', '6', index: 15, input: 'abbb34eftab0modabbbbb6', groups: undefined]
var execArr4 = reg.exec(str)
console.log(execArr4)
// null
2
3
4
5
6
7
8
9
exec
中不管是不是全局的匹配,只要没有子表达式,其返回的都只有一个元素,如果是全局匹配,可以利用 lastIndex
进行下一个匹配,匹配成功后 lastIndex
的值将会变为上次匹配的字符的最后一个位置的索引。在设置 g
属性后,虽然匹配结果不受 g
的影响,返回结果仍然是一个数组(第一个值是第一个匹配到的字符串,以后的为分组匹配内容),但是会改变 index
和 lastIndex
等的值,将该对象的匹配的开始位置设置到紧接着匹配子串的字符位置,当第二次调用 exec
时,将从 lastIndex
所指示的字符位置 开始检索。同样 match
方法在设置了 g
属性后,也会改变 index
和 lastIndex
的值,但是是一次性的。无法像 exec
那样能逐过程累积,因此无法累积获取下一次检索的位置。
注意:在 while
循环中,当没有全局的变量 g
时,由于 index
和 lastIndex
的值不会变化(除非手动修改),则会导致每次的匹配都是从字符串的头开始的,所以只要字符串中有匹配,就会导致死循环,当时设置 g
后,会自动改变前面的两个属性,会依次向后匹配直到没有匹配项退出循环