regExp.exec和string.match
二者都是根据正则匹配字符串的作用,但是区别在于二者的返回结果在不同正则模式(组、全局)是不通的
1.全局匹配正则
// 带有全局匹配标志g,exec依次匹配出所有符合条件的内容
var reg = /.at/g;
var str = '1at,2at,3at'
let match
while ((match = reg.exec(str)) !== null) {
console.log(match)
// ['1at', index: 0, input: '1at,2at,3at', groups: undefined]
// ['2at', index: 4, input: '1at,2at,3at', groups: undefined]
// ['3at', index: 8, input: '1at,2at,3at', groups: undefined]
}
console.log(str.match(reg))
// ['1at', '2at', '3at']
// 如果去掉全局匹配标志,则每次都从第一个开始匹配
var reg = /.at/;
var str = '1at,2at,3at'
let match
while ((match = reg.exec(str)) !== null) {
console.log(match)
// ['1at', index: 0, input: '1at,2at,3at', groups: undefined]
// 陷入死循环无法跳出while
}
console.log(str.match(reg))
// ['1at', index: 0, input: '1at,2at,3at', groups: undefined]
上述代码中可以看出,在全局匹配正则下
reg.exec:依次返回‘1at’:每一个匹配到的内容,0:当前匹配到内容的下标,‘1at,2at,3at’:被匹配对象
str.match:返回所有符合规则的内容但是不返回下标
注意:全局匹配指 后一次匹配从上一次匹配结果出往后继续匹配。
而在非全局匹配中
reg.exec:返回格式一样,但是每次都匹配第一个
str.match:和reg.exec返回结果相同
2.组匹配正则
// 在组匹配中,这个正则先匹配.at在匹配.a
var reg = /(.a)t/
var str = '1at,2at,3at'
while ((match = reg.exec(str)) !== null) {
console.log(match)
// ['1at', '1a', index: 0, input: '1at,2at,3at', groups: undefined]
// 陷入死循环
}
console.log(str.match(reg))
// ['1at','1a', index: 0, input: '1at,2at,3at', groups: undefined]
// 组+全局
var reg = /(.a)t/g
var str = '1at,2at,3at'
while ((match = reg.exec(str)) !== null) {
console.log(match)
// ['1at', '1a', index: 0, input: '1at,2at,3at', groups: undefined]
// ['2at', '2a', index: 4, input: '1at,2at,3at', groups: undefined]
// ['3at', '3a', index: 8, input: '1at,2at,3at', groups: undefined]
}
console.log(str.match(reg))
// ['1at', '2at', '3at']
组匹配通常用于匹配所需要的内容。上述可见在组匹配时,二者的区别也是完全相同的
总结:String.match和regExp.exec二者的区别在于正则为全局匹配时 ,regExp.exec能够更全面的依次返回内容和对应下标。而String.match只有在非全局是会返回下标,如果需要实现和regExp.exec相同的功能,需要使用String.matchAll
这是一段实用代码
/*
当前需求:用户传入的字符串用‘’切割成一个一个字符存入一个空数组
中,但是输入字符串中的‘~’和‘*’中间的内容不做切割直接整体存入新数组
中不保留~和*两个标志符号。数组不打乱字符串的顺序
*/
let dataPool = []
const startPrint = arr => {
let input = arr[0]; // 记录传入的arr
const regex = /~(.*?)\*/g; // 用于匹配字符串全局中的~开头和*结尾的内容
let lastIndex = 0; // 当前值
let match; // 匹配到的符合条件的字符串段
while ((match = regex.exec(input)) !== null) {
// 这个while循环会依次匹配所有符合正则的内容
const beforeMatch = input.slice(lastIndex, match.index);
beforeMatch.split('').forEach(char => dataPool.push(char));// 记录匹配到的第一个符合条件内容之前的并切割放入dataPool中
dataPool.push(match[1]);// 匹配到的第一个不切割放入dataPool中
lastIndex = match.index + match[0].length; // 更新当前值为第一个匹配内容下标+长度用于和第二次匹配内容进行截取
}
// 后面还有内容则切割进dataPool中
const remainingContent = input.slice(lastIndex);
remainingContent.split('').forEach(char => dataPool.push(char));
};