JavaScript replace() 方法支持函数作为第二个参数,其回调函数参数顺序固定:完整匹配字符串、各捕获组内容、起始索引、原字符串;命名捕获组额外提供 groups 对象;全局标志 g 决定调用次数;常见错误包括漏写 return、正则未转义、忽略 g 标志等。
JavaScript 的 replace() 方法支持用函数作为第二个参数,这是处理动态、条件化替换的核心能力。关键不在于“能不能”,而在于“参数怎么对得上”——传错顺序或忽略全局标志,结果就容易出人意料。
当正则表达式匹配成功时,回调函数按固定顺序接收若干参数,顺序不能乱:
$&)())匹配的内容,对应 $1、$2…;没有捕获组时,这部分不存在replace 的那个字符串)例如:'a1b2'.replace(/(d)/g, (match, p1, offset, str) => `【${p1}】@${offset}`) → "a【1】@1b【2】@3"。
ES2018 起支持命名捕获,如 /(?<year>d{4})-(?<month>d{2})/</month></year>。此时回调函数末尾会多一个 groups 对象参数(在 string 之后),它包含所有命名组的键值对:
立即学习“Java免费学习笔记(深入)”;
'2023-04'.replace(/(?<y>d{4})-(?<m>d{2})/, (_, _, __, ___, str, {y, m}) => `${m}/${y}`)</m></y> → "04/2023"
groups 对象里,不会额外塞进位置参数列表有 g 标志,回调对每次匹配都执行一次;没 g,哪怕正则能匹配多次,也只调用一次(仅首次匹配):
'x1 y2 z3'.replace(/(d)/g, (_, d) => `N${d}`) → "xN1 yN2 zN3"
'x1 y2 z3'.replace(/(d)/, (_, d) => `N${d}`) → "xN1 y2 z3"(只换第一个)g,而不是回调写错了实际编码中几个高频出错点:
undefined,整个匹配被删掉(如 return 忘写或写成 console.log).、$)→ 匹配失败,回调根本不会触发$1 等变量名但用了函数 → 这些符号在函数模式下无效,必须靠参数取值m 或 s 标志 → ^、$ 或 . 行为不符合预期写回调前先确认正则是否真能匹配上,再检查参数数量和顺序,基本就不会卡在“为什么没反应”上。