string.prototype.replace()支持回调函数,可动态生成替换结果;回调参数依次为匹配字符串、捕获组、起始索引和原字符串;利用闭包可实现计数、去重等状态化替换;通过正则分组与条件判断能精准控制替换逻辑。
javascript 的 string.prototype.replace() 方法支持传入回调函数,这使得它不仅能做简单替换,还能根据匹配内容动态生成替换结果,实现条件判断、计数、格式转换等复杂逻辑。
回调函数的参数含义
当使用正则表达式调用 replace() 并传入函数时,回调会收到多个参数:
-
第一个参数:完整匹配的字符串(即
match) -
后续参数:依次为每个捕获组(
$1,$2…)匹配的内容(如果有) -
倒数第二个参数:当前匹配在原字符串中的起始索引(
offset) -
最后一个参数:原始输入字符串(
string)
例如:'a1b2c3'.replace(/(\d)/g, (m, g1, offset, str) => `【${g1}】at ${offset}`) → 'a【1】at 1b【2】at 3c【3】at 5'
实现带状态的替换(如编号、去重)
利用闭包或外部变量,可在多次回调中维持状态。常见场景包括自动编号、按出现顺序标记、跳过重复项等。
示例:给每个数字加序号
let count = 0;
'price: 199, discount: 29'.replace(/\d+/g, (match) => `N${++count}:${match}`);
// → 'price: N1:199, discount: N2:29'
更安全的做法是封装成可复用函数,避免全局变量污染:
function withCounter() {
let i = 0;
return () => `N${++i}`;
}
'x1y2z3'.replace(/\d/g, withCounter()); // 'xN1yN2zN3'
基于捕获组和上下文做条件替换
通过分析捕获组内容或 offset 位置,可决定如何替换。比如只替换引号外的单词、跳过注释行、保留特定前缀等。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
示例:将所有未被单引号包裹的 id 替换为 userId,但保留 'id' 不变
const text = "id: 123, name: 'id', data.id = 456"; text.replace(/(?:'[^']*')|(\bid\b)/g, (match, group1) => group1 ? 'userId' : match ); // → "userId: 123, name: 'id', data.userId = 456"
原理:正则优先匹配整个引号字符串(不捕获),仅当不匹配时才捕获 id 单词;回调中若 group1 存在说明命中目标,否则原样返回(即保留引号内容)。
返回空字符串或跳过匹配
回调函数返回空字符串 '' 即删除该匹配;返回 undefined 或不返回,则默认转为空字符串。注意:不能靠 return 后无值来“跳过”,必须显式控制返回值。
常见误写:
// ❌ 错误:没返回值 → 替换为空字符串
str.replace(/\d/g, (m) => { if (m > 5) return m; });
// ✅ 正确:兜底返回原匹配
str.replace(/\d/g, (m) => m > 5 ? m : m);
// 或者明确跳过某些情况
str.replace(/\d/g, (m) => +m % 2 === 0 ? `(${m})` : m);
若需完全跳过某次匹配(即不替换、也不删除),就返回原 match 字符串即可。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










