【问题标题】:Replacing multiple occurrences of dynamic strings?替换多次出现的动态字符串?
【发布时间】:2026-02-01 14:55:01
【问题描述】:

不确定我是否可以在标题中更好地解释,但在这里解释得更好。我正在尝试创建一个充当简单“模板”的函数。我给它一个带有某些标签“{{name}}”的字符串,它会用某个字符串替换它。

这是我目前所拥有的:

调用函数:

loadTemplate("<div>{{name}}, {{anotherString}}</div>", {
    name: "Hunter",
    anotherString: "is amazing!!!!" 
});

功能:

// Created this to make my life easier :)
function loadTemplate(template, data) {
    var tags = template.split("{{").pop().split("}}").shift();
    console.log(tags); // This only gives me the last occurrence.
}

如何循环遍历字符串中所有出现的 {{variable}} 以便将其替换为相关数据?

类似于Handlebars.js(我想要一个超级轻量级​​和快速的功能,而不是一个完整的插件)

【问题讨论】:

标签: javascript jquery regex performance


【解决方案1】:

data 对象中的每个键进行搜索/替换:

function loadTemplate(template, data) {
  var RE, d;
  for(d in data) {
    RE= new RegExp('{{'+d+'}}', 'g');
    template= template.replace(RE, data[d]);
  }
  console.log(template);
}

loadTemplate("<div>{{name}}, {{anotherString}}</div>", {
  name: "Hunter",
  anotherString: "is amazing!!!!" 
});

【讨论】:

  • 我知道如何替换数据,是“正则表达式”或循环部分让我感到困惑。我将彻底准备好有关它的文档。谢谢。
【解决方案2】:

使用替换文本的回调进行一个正则表达式替换非常容易:

function loadTemplate(template, data) {
    return template.replace(/\{\{(\w+)\}\}/g, function(match, key) {
        return data[key];
    });
}

alert(loadTemplate("<div>{{name}}, {{anotherString}}</div>", {
    name: "Hunter",
    anotherString: "is amazing!!!!" 
}));

模式是\{\{(\w+)\}\},意思是{{,后面跟着一个捕获的单词,然后是}}。单词是字母数字字符和下划线的任意序列。

如果您希望能够使用不包含}} 的任何键值(例如,带有空格),您可以将\w+ 替换为.+?

function loadTemplate(template, data) {
    return template.replace(/\{\{(.+?)\}\}/g, function(match, key) {
        return data[key];
    });
}

alert(loadTemplate("<div>{{The Name}}, {{Another $tring}}</div>", {
    "The Name": "Hunter",
    "Another $tring": "is amazing!!!!" 
}));

【讨论】:

  • 也感谢您的回答。在您和 Rick 之间,使用正则表达式是否存在速度问题?我听说它们可能很慢。
  • 嗯...我的会更快,因为它会进行一次替换。 Rick's 对data 中的每个键进行一次替换,并为每个键编译一个正则表达式。但是,如果这对您很重要,您应该对性能进行基准测试。此外,在这种情况下,正则表达式不应该很慢,因为它们基本上是由 JS 解释器运行的,它可以通过 not 创建临时字符串来优化执行速度。我相信它们会比您使用脚本代码中的字符串操作自己做的任何事情都要快。
  • 看看这个,这个测试是否“准确”:jsfiddle.net/fy3dcmqb
  • 对于给定的输入,@LucasTrzesniewski 的答案确实比我的快了大约。 0.15%(在 Chrome 中):jsperf.com/elite-gamer-regexp
  • @RickHitchcock 由于性能,我将答案授予卢卡斯(因为我要求尽可能快速、简单的方法),但您也回答了我的问题。谢谢。
【解决方案3】:

我喜欢你的“拆分”想法,我说坚持下去:

window.loadTemplate = function(template, data) {
    var i = 0;
    var bool = true;
    while (bool) {
        try {
        var tags = template.split("{")[i+2].split("}")[0];
        alert(tags);
        i+=2;
        } catch (e)
        {
            bool = false;
        }
    }
}
td {
    border: black solid 1px;
}
&lt;button type="button" onclick="loadTemplate('&lt;div&gt;{{name}}, {{anotherString}}&lt;/div&gt;', {name: 'Hunter', anotherString: 'is amazing!!!!' })"&gt;Load Template&lt;/button&gt;

【讨论】: