如何用JS正则将模板插值与普通文本转换为合法表达式语法?
解决模板字符串转换问题
问题分析
你需要把带{{...}}插值的字符串转换为:移除插值的双花括号保留内容,非插值文本用单引号包裹,各部分用+连接。原来的正则会把所有内容(包括插值变量)都加单引号,还没处理+连接,核心问题是没区分插值和普通文本的处理逻辑,也没做拼接。
解决方案
改用正则匹配两种片段(插值/普通文本),通过回调逻辑分别处理后再拼接:
- 用正则
/({{(.*?)}})|([^{}]+)/g匹配所有插值片段{{xxx}}或普通文本片段(非花括号的内容) - 对每个匹配结果判断:
- 若为插值片段,直接提取花括号内的内容
- 若为普通文本,用单引号包裹
- 最后把所有处理后的片段用
+连接
修改后的代码:
const strs = [ 'foo{{bar}}', '{{foo}}bar', 'foo{{bar}}baz', '{{foo}}{{bar}}', 'foo', '{{foo}}', '{{foo}}bar{{baz}}' ]; let result = strs.map((s) => { // 拆分字符串为插值/普通文本片段 const parts = s.match(/({{(.*?)}})|([^{}]+)/g) || []; return parts.map(part => { // 判断片段类型并处理 if (part.startsWith('{{')) { return part.slice(2, -2); // 移除双花括号 } else { return `'${part}'`; // 普通文本加单引号 } }).join(' + '); }); result.forEach((r) => console.log(r));
输出结果
运行后会得到符合要求的结果:
'foo' + bar foo + 'bar' 'foo' + bar + 'baz' foo + bar 'foo' foo foo + 'bar' + baz
补充说明
- 用
match拆分片段比多次replace更清晰,能精准区分两种内容 - 加
|| []避免match返回null导致报错 - 如果普通文本包含单引号,可以额外加转义逻辑,比如把
part里的'替换为\'
内容的提问来源于stack exchange,提问作者Jon Sud
相关产品推荐
相关产品推荐

