字符串对象共有 4 个方法,可以使用正则表达式:match()、replace()、search()和split()。
ES6 将这 4 个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上。
RegExp.prototype[Symbol.match]RegExp.prototype[Symbol.replace]RegExp.prototype[Symbol.search]RegExp.prototype[Symbol.split]如果一个正则表达式在字符串里面有多个匹配,现在一般使用g修饰符或y修饰符,在循环里面逐一取出。
((log) => {
const regex = /t(e)(st(\d?))/g;
const string = 'test1test2test3';
const matches = [];
let match;
while (match = regex.exec(string)) {
matches.push(match);
}
log(matches);
// [
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"],
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"],
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
// ]
})(console.log)
上面代码中,while循环取出每一轮的正则匹配,一共三轮。
目前有一个提案,增加了String.prototype.matchAll方法,可以一次性取出所有匹配。不过,它返回的是一个遍历器(Iterator),而不是数组。
((log) => {
const string = 'test1test2test3';
// g 修饰符加不加都可以
const regex = /t(e)(st(\d?))/g;
for (const match of string.matchAll(regex)) {
log(match);
}
// ["test1", "e", "st1", "1", index: 0, input: "test1test2test3"]
// ["test2", "e", "st2", "2", index: 5, input: "test1test2test3"]
// ["test3", "e", "st3", "3", index: 10, input: "test1test2test3"]
})(console.log)
上面代码中,由于string.matchAll(regex)返回的是遍历器,所以可以用for...of循环取出。
相对于返回数组,返回遍历器的好处在于,如果匹配结果是一个很大的数组,那么遍历器比较节省资源。
遍历器转为数组是非常简单的,使用...运算符和Array.from方法就可以了。
// 转为数组方法一
[...string.matchAll(regex)]
// 转为数组方法二
Array.from(string.matchAll(regex));
目前这个提案处于stage 04的阶段,但是预计实现年份是2020,所以暂时不要在生产环境中使用这个方法。