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 会用到的地方多一点
...