导读:本期聚焦于小伙伴创作的《如何用正则与函数式替换高效处理字符串中的$1和${2}占位符?》,敬请观看详情。占位符替换看似简单,但混合使用$1与${2}这类写法时,原生replace很容易出错。直接拼接字符串不仅难维护,遇到特殊字符还会破坏结构。本文从匹配规则入手,说明如何用正则捕获组配合替换函数,统一解析两种占位符。相较手动切分,函数式替换能避免索引错位,也方便接入默认值与类型转换。掌握这套思路后,无论是配置渲染还是接口报文拼装,都能用少量代码稳住正确率。

在后端渲染配置、前端拼装请求报文或做国际化文案时,我们常遇到同时包含$1${2}的模板字符串。这两种写法语义接近,但原生字符串处理函数很难一次性吃下。如果只用简单的split再join,遇到${1}里带花括号、或数字后面紧跟普通字符的情况就会断掉。更稳妥的做法是用一条正则把两类占位符都捕获出来,再交给replace的回调函数做映射。

如何用正则与函数式替换高效处理字符串中的img和 src=

一、占位符的匹配规则拆解

先说$1这种写法:它通常以美元符号开头,后面紧跟一个或多个数字,且数字后不能是左花括号(否则应算${1})。而${2}则是美元符号加左花括号、里面是数字、再跟右花括号。两者可以合并成一条正则:用分支匹配,一组抓$数字,一组抓${数字}。注意要对$做转义,写成$

下面这条正则就能覆盖常见情况:$(d+)|${(d+)}。前半段$(d+)匹配不带花括号的形式,捕获组1拿到数字;后半段${(d+)}匹配带花括号的形式,捕获组2拿到数字。因为用了或,回调函数里要判断哪个组有值。这样无论模板里混用多少种写法,都能逐个替换。

二、用函数式替换完成映射

JavaScript的String.prototype.replace支持第二个参数传函数。函数接收匹配内容、各个捕获组、偏移量和原串,返回用来替换的文本。我们只要在函数中根据捕获组取出对应数据,就能实现灵活替换。相比传入字符串做替换,函数式不会把$再当成特殊符号,也方便加默认值。

看一段完整示例,假设数据存在数组里:

// 模板与数据
var tpl = '用户$1在${2}购买了$3件${4}';
var data = ['张三', '2023-09-01', 2, '苹果'];

// 正则:匹配 $数字 或 ${数字}
var reg = /$(d+)|${(d+)}/g;

var result = tpl.replace(reg, function (match, p1, p2) {
  // p1对应$数字,p2对应${数字}
  var index = p1 ? parseInt(p1, 10) : parseInt(p2, 10);
  var val = data[index - 1];
  // 若数据缺失给默认值
  return val === undefined ? '' : String(val);
});

console.log(result);
// 输出:用户张三在2023-09-01购买了2件苹果

上面代码里,reg用了全局标志g,所以会替换所有占位符。回调函数里先判断p1p2哪个有值,再算数组下标。由于模板里数字从1开始,而数组从0开始,因此用了index - 1。这种写法比手写循环切分字符串要可靠得多。

三、进阶:支持默认值与格式化

真实项目里,占位符可能写成${2:默认名}或要求把数字格式化。我们可以在正则里多加一个捕获组存默认值,然后在函数里判断。如果对应数据为空,就返回默认值。这样模板作者就能在字符串里自描述兜底逻辑。

示例如下:

var tpl = '姓名${1:匿名},年龄$2岁';
var data = [undefined, 18];

// 支持 ${n:默认值}
var reg = /$(d+)|(${(d+)(?::([^}]*))?})/g;

var out = tpl.replace(reg, function (m, p1, p2, p3, p4) {
  var idx = p1 ? parseInt(p1, 10) : parseInt(p3, 10);
  var def = p4; // 默认值
  var v = data[idx - 1];
  if (v === undefined || v === null || v === '') {
    return def !== undefined ? def : '';
  }
  return String(v);
});

console.log(out);
// 输出:姓名匿名,年龄18岁

这里正则后半段用(?::([^}]*))?可选组抓冒号后的默认值。虽然正则变长,但可读性仍可控。函数式替换让我们在JS侧做任何加工,比如把日期转成本地格式、把金额除以一百,都不会污染模板本身。

四、与其他方案的对比

有人习惯用第三方模板引擎,比如把${x}丢给现成库。但引入依赖会增加包体,且多数库不认$1这种短写。自己用正则加函数替换,零依赖、可控性强,也更容易单元测试。下表列出差异:

方案支持$1支持${n}依赖灵活性
手动split
正则+函数替换
模板引擎多数不支持

从表里能看出,正则加函数替换在零依赖前提下覆盖了两种占位符,还能顺手做默认值。对小型工具、脚本或嵌入式页面来说,是最省事的做法。只要注意正则转义与下标换算,基本不会踩坑。

五、常见误区提醒

一个容易错的地方是:在replace的字符串参数里写$1会被当成引用捕获组,而不是原样输出。所以如果映射值里含有$符号,必须用函数返回,不能在字符串替换里直接拼。另一个误区是忘记全局标志g,导致只换第一个占位符。只要避开这两点,这套方法就很稳。

总结来看,用一条分支正则捕获$数字${数字},配合replace的回调函数,是处理混合占位符最直接、轻量的方式。它既不需要重框架,也能应对默认值和格式化需求,适合绝大多数字符串模板参数替换场景。

正则表达式函数式替换字符串模板修改时间:2026-08-08 14:21:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。