3/3 简单分析 JavaScript 中 match、 exec、 replace 的区别

写在前面

  仅供自用

  ...


exec

  对于 exec 来说,如果标签是 g 

  那么相当于 返回的是 ( 或者说 更新的是这个 正则表达式 ) 下一次 检索的 位置 lastIndex

  和 一个 匹配的数组 ( 主要是捕获组 )

  1. lastIndex

let text = "cat, bat, sat, fat";
let pattern = /.at/g; // 标记是 全局标记

let matches = pattern.exec(text);
console.log(matches.index); // 0 找到的第一个匹配的 位置
console.log(matches[0]);    // cat
console.log(pattern.lastIndex); // 3 返回的是下一次的检索位置

matches = pattern.exec(text); 
console.log(matches.index); // 5 找到的第一个匹配的 位置
console.log(matches[0]);    // bat
console.log(pattern.lastIndex);  // 8 

matches = pattern.exec(text);
console.log(matches.index);
console.log(matches[0]);
console.log(pattern.lastIndex);

  

  当然 因为 是对于 正则表达式 实例 记录更新的 lastIndex

  所以 会出现下面的情况

let text = "cat, bat, sat, fat";
let pattern = /.at/g; // 标记是 全局标记

let matches = pattern.exec(text);
console.log(matches.index); // 0 找到的第一个匹配的 位置
console.log(matches[0]);    // cat
console.log(pattern.lastIndex); // 3 返回的是下一次的检索位置

matches = pattern.exec("test 'isLastIndexFreshed' cat, bat, sat, fat"); 
console.log(matches.index); // 26 找到的第一个匹配的 位置
console.log(matches[0]);    // bat
console.log(pattern.lastIndex);  // 29 

matches = pattern.exec(text);
console.log(matches.index);  // 开始报错 因为记录了 这一次的起始位置 29 越界了
console.log(matches[0]);
console.log(pattern.lastIndex);

  

  2. 对于捕获组

  ok 说完了 lastIndex 

  我们可以看一下 matches 里面到底是些什么

  对于没有 捕获组 的东西 ( 就是正则表达式 中的 括号 )

  只是 会 匹配 第一个匹配到的 东西

  

  那么如果 我们 加一个 括号

  

  你会发现这个

  

  其实 第一个 是匹配的 字符串

  第二个是 符合条件的 匹配组

  这里还是 出不来 一组 满足条件 的 数组

  只能顺次 查找

 match

  match 这个就很简单了 直接返回匹配 正则表达式 的所有匹配项 数组

  

   

  注意 这里得加一个 g 标志

  那么如果我们可以通过 写一个循环来用 exec 实现 match

let text = "cat, bat, sat, fat";
let pattern = /.at/g;
// pattern.lastIndex = 5;
//  相当于 match
let arr = [];
while(pattern.lastIndex != text.length){
    let matches = pattern.exec(text);
    console.group(matches[0]);
    arr.push(matches[0]);
    console.log(pattern.lastIndex+" " + text.length)
    console.groupEnd();
}
console.log(arr);

// match 
console.log(text.match(pattern));

 replace

  replace 在使用的情况下,我发现

  这个东西相当于  以上两者的结合

  或者说 是 一种 近似的 迭代

  现在 给一个 例子

let text = "cat, bat, sat, fat";
let pattern = /(.at)/g;

  当我们使用 match 的时候

let text = "cat, bat, sat, fat";
let pattern = /(.at)/g;
while(pattern.lastIndex != text.length){
let matches = pattern.exec(text);
console.log(matches);
}

  可以看到 (.at) 是一个捕获组

  

  当我们使用 replace 的时候

let text = "cat, bat, sat, fat";
let pattern = /(.at)/g;
let result = text.replace(pattern,"word ($1)");  // $1 的意思是 第一个捕获项
console.log(result);

  我们会发现 $1 其实 就是相当于 每次使用 exec 的时候那个 第一个捕获组

   

     当时 还觉得 $1 会一直是 cat 但是 并不是...

  这个并不是 一维的想法 其实要从二维 来看...

  $1 是 第一个 捕获组

  ((x)) 这种 就有两个 捕获组 一个是内层 一个是外层...

总结

  总的来说 

  match 会用到的地方多一点  

  ...

Let it roll
原文地址:https://www.cnblogs.com/WaterMealone/p/14476561.html