Fork Me On Github

js 实现一个正则替换

代码

/**
 * 正则匹配替换
 * @param content 
 * @param pattern 
 * @param cb 
 * @returns 
 */
export function regexReplace(content: string, pattern: RegExp, cb: (match: RegExpExecArray) => string): string {
    if (content.length < 1) {
        return content;
    }
    const matches: RegExpExecArray[] = [];
    let match: RegExpExecArray|null;
    while (null !== (match = pattern.exec(content))) {
        matches.push(match as RegExpExecArray);
    }
    const block: string[] = [];
    for (let i = matches.length - 1; i >= 0; i--) {
        match = matches[i];
        block.push(content.substr(match.index + match[0].length));
        block.push(cb(match));
        content = content.substr(0, match.index);
    }
    return content + block.reverse().join('');
}

原理

  1. 先获取所有的匹配结果,存入一个临时数组中
  2. 倒序执行回调方法获取替换的内容
  3. 按照匹配到的位置,截断字符串,把匹配到的部分根据长度去除,然后按倒序和替换的字符串存入一个数组,
  4. 颠倒数组顺序连接即最终结果

疑问

Q:为什么不在匹配时边匹配边替换?

A:原本我这样做的,发现匹配结果出错了,有些没匹配到。因为exec 匹配时正则表达式会记住最后的匹配位置,如果原本的内容长度变化;,就会导致这个位置不正确。

Q:为什么要截断字符串?

A: 使用字符串替换会搜索全部,多一些不必要的操作;截断存入数组,就是想最后一起做拼接。

Q: 为什么要倒序替换?

A: 因为正序截取的话会导致匹配结果中的位置要进行改变。

点击查看全文
0 21 0