JavaScript 的 replace() 方法,很多开发者刚接触时容易疑惑:明明“看起来”把字符串里的“a”全部替换成了“x”,结果却发现只改了第一个?先别急着怀疑代码逻辑,这其实是它对“字面量”模式的坚持——如果你只传入一个字符串作为参数,它默认只替换第一个匹配项。真正的强大之处,在于结合正则表达式来使用。

它的底层机制其实很清晰:字符串字面量模式并不关心“全局”,只有正则表达式中的 g 标志才能通知引擎:全部找出,一个不漏。加上 i 标志?大小写不敏感,完美实现。还想精准定位?锚点 ^、$ 搭配多行 m 标志,能让你只替换每行开头的内容。特殊字符需要转义?比如想要替换点号 .,必须写成 \.,否则它会被当作万能通配符处理。
这是基础,也是进阶的门槛。
第二个技巧:捕获组的“占位符”能力
正则里的括号 () 不仅仅是分组,它更像一个“临时存储区”,捕获到的内容可以在替换字符串中直接引用,省去手动提取的麻烦。例如你有一个日期字符串 "2026-05-20",想转成 "05/20/2026",一行代码就能完成:$2/$3/$1。这里的 $1、$2、$3 就是捕获组按顺序对应的索引。
还有几个更实用的特殊变量:$& 代表整个匹配到的文本,在添加方括号、包裹前缀后缀时非常顺手。更隐蔽的是 $`(反引号)和 $'(单引号),分别表示匹配位置之前和之后的内容,这种上下文感知的替换,在设计 DSL 或模板语言时尤其有用。当然,如果想字面输出美元符号,写两个 $$ 即可。
第三个技巧:让替换逻辑“活”起来
当替换规则不再是固定的字符串,而是依赖于匹配内容本身(例如转大写、合并计算、条件判断),传入一个字符串参数就完全不够用了。此时,第二个参数传一个函数,才是真正的“杀手锏”。
函数接收的参数顺序是固定的:首先是整个匹配的字符串,接着是第一个捕获组,第二个捕获组……以此类推,最后两个分别是匹配的起始索引和原始字符串。你可以在这个函数里做任何处理——比如将单词首字母大写:"hello world".replace(/\b\w/g, c => c.toUpperCase())。或者处理更复杂的场景,比如给价格加税:遍历所有金额数字,乘以1.1,再格式化为两位小数。
函数内部可以校验、格式化,甚至启动异步请求(不过需要结合 Promise 链来处理),灵活性远超静态字符串。
但需要注意一个常被忽略的陷阱:replace() 从不修改原字符串,它总是返回一个新的字符串。而且它只能对字符串类型生效。数字、布尔等类型必须先转字符串,否则直接调用会报错。稳妥的做法是 String(val).replace(...)。如果只是简单的全局字面替换,ES2021 引入的 replaceAll() 语法更直观,但要记住它不支持正则,两者各有适用的场景。
总结一下:replace() 是强大的工具,但要用好它,需要理解正则与字符串配合的微妙之处。希望这几个要点能帮你避开常见的坑,写出更干净、更高效的代码。
