【问题标题】:JavaScript replace tokens in curly bracesJavaScript 替换花括号中的标记
【发布时间】:2021-05-10 15:15:42
【问题描述】:

所以我之前的问题很糟糕,所以我正在编辑这个问题。

我有这样的对象/json

{
"title": "Hello {USER}",
"description": "Today you earned {AMOUNT} dolars
}

我将此数据发送到 api,因此它会返回一条特殊消息。但问题是我需要替换 {USER} 和 {AMOUNT} 而无需获取值、更改它并重新分配它等等。这就像替换但对于对象,所以在不更改对象和做复杂事情的情况下,我可以动态更改 {USER}并且 {AMOUNT} 用户来自 api 并且 AMOUNT 是一个随机数我只需要更改 {} 括号而不会使事情变得太复杂

【问题讨论】:

标签: javascript


【解决方案1】:

String.prototype.replaceAll()

返回

一个新字符串,其中 all 匹配的模式被替换替换。

var obj = {
"title": "Hello {USER}",
"status": "You look {STATUS} today"
};
function replaceTokens(name, value, str){
  return str.replaceAll("{"+name+"}", value);
}
obj.title = replaceTokens("USER", "Mark", obj.title);
obj.status = replaceTokens("STATUS", "great", obj.status);
console.log(obj);

【讨论】:

    【解决方案2】:

    您可以使用regex 替换花括号中的文本:

    function replaceText(text, value) {
      const regex = /\{.*\}/;
      return text.replace(regex, value);
    }
    
    const TEXT = 'Hello {USER}';
    console.log(replaceText(TEXT, 'Mark'));

    【讨论】:

    • 这种技术更容易被不符合字符串插值语法的大括号混淆。
    • 这取决于它的应用范围。我认为对于小字符串来说这不是问题。
    【解决方案3】:

    这是一种使用正则表达式定位{KEY} 并在字典中查找KEY 以执行替换的方法。对于键名的语法,我使用了 A-Z 加下划线的保守语法。

    这个版本返回一个新对象(不改变原来的对象)。

    function interpolateObject(obj, dict) {
      return Object.fromEntries(Object.entries(obj).map(interpolateEntry));
    }
    
    function interpolateEntry([key, val]) {
      if (typeof val !== 'string') return [key, val];
      return [key, interpolateString(val, dict)];
    }
    
    function interpolateString(str, dict) {
      return str.replace(/\{([A-Z_]+)\}/g, (original, key) => dict.hasOwnProperty(key) ? dict[key] : original);
    }
    
    const template = {
      "title": "Hello {USER}",
      "status": "You look {STATUS} today",
    };
    const dict = { USER: 'Mark', STATUS: 'great' };
    console.log(interpolateObject(template, dict));

    如果需要,您还可以编写一个就地修改对象的版本。

    // Alternate approach, modifies object in place.
    function interpolateObjMutate(obj, dict) {
      for (const key in obj) {
        if (typeof obj[key] === 'string') obj[key] = interpolateString(obj[key], dict);
      }
    }
    

    【讨论】:

    • 我需要在多个文件夹上使用它,为此我需要再次编写它,如果我导出它,我会得到 dict is not defined from interpolateEntry 因为 dict 没有定义,我有点可以找不到办法克服这个问题,我显然仍然不擅长 js
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-19
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多