【问题标题】:Javascript Pattern ReplaceJavascript 模式替换
【发布时间】:2014-02-01 09:09:55
【问题描述】:

我有一个这样的对象

myObj = {
    "strPattern": "Name: #name#<br>Surname: #sname#<br>Location: #loc#",
    "name": "John",
    "sname": "Doe",
    "loc": "LA"
}

现在我需要一个函数,它可以接收我的对象并在其模式的帮助下将其作为字符串返回。

预期结果:"Name: John&lt;br&gt;Surname: Doe&lt;br&gt;Location: LA"

我不能用 JavaScript 的 replace 方法做到这一点,我不知道该怎么做。感谢您的帮助。

顺便说一下,subStrs 的数量可以是动态的。例如,此示例中有 3 个子字符串,但对于其他对象,它可以是 5 或 10。 #age#、#gender# 等...

【问题讨论】:

  • 我知道你有答案,但你可能想看看实际的模板引擎,如 ejs、车把等

标签: javascript


【解决方案1】:

您可以使用for (var key in myObj) 结构循环到对象属性。在每个循环中,key 变量保存每个属性的名称,您可以使用 myObj[key] 变量访问其值。

如何在您的场景中使用的示例可能是这样的。

var myObj = {
    "strPattern": "Name: #subStr1#<br>Surname: #subStr2#<br>Location: #subStr3#",
    "subStr1": "John",
    "subStr2": "Doe",
    "subStr3": "LA"
};

var html = myObj["strPattern"];

for (var key in myObj) {
   var obj = myObj[key];
    if(key !== "strPattern") {
        html = html.replace("#" + key + "#",obj);
    }
}

jQuery('#result').html(html);

我还用它制作了jsfiddle

编辑:正如@Andreas 在评论中提到的,不能保证访问属性的顺序,我相应地调整了我的代码 sn-p。

【讨论】:

  • @Andreas -- 尽管规范说不,每个实现都说是。但即便如此,我也不喜欢这样。 var html = myObj.strPatternif( key === 'strPattern' ){ continue; } 更好。
  • 你的替换应该是html.replace( new RegExp( '#' + key + '#', 'g' ), obj ) ) 以允许相同模式的多个实例
  • @zyklus 但不能保证,因此您不应该依赖。我不知道目前的情况,但有时订单的执行方式不同(v8 - Issue 164
  • @Andreas -- 嗯,如果你需要的话,你可以依赖它,只要你知道它可能会在某个时候坏掉(即使这不太可能)。你的页面更可能因为 JS 被禁用而不是因为这个原因而崩溃
【解决方案2】:

以下功能可用于提高性能。但是,如果您不需要多次使用该模板,它是没有用的。

function compile(tpl) {
    tpl = tpl.split(/#(.*?)#/);
    return Function('return [' + tpl.map(function (v, i) {
        if (i % 2) return 'this["' + v + '"]';
        return v && '"' + v.replace(/"/g, '\\"') + '"';
    }).join(',') + '].join("");');
}

使用示例:

var myObj = {
    "strPattern": "Name: #name#<br>Surname: #sname#<br>Location: #loc#",
    "name": "John",
    "sname": "Doe",
    "loc": "LA"
};

myObj.strPattern = compile(myObj.strPattern).call(myObj);

更有趣:

var tpl = '#first# #last#',
    compiled = compile(tpl);

compiled.call({ first: 'John', last: 'Doe' }); // "John Doe"
compiled.call({ first: 'Walter', last: 'White' }); // "Walter White"

更多细节在这里:https://stackoverflow.com/a/20886377/1636522

【讨论】:

    【解决方案3】:

    解决此问题的另一种方法是:仅通过字符串中出现的替换来工作:

    var Stringify = function(obj){
      return obj.strPattern.replace(/#([a-z]+)#/gi, function(match,group){
        return obj[group] || match;
      });
    };
    
    var str = Stringify({
      "strPattern": "Name: #name#<br>Surname: #sname#<br>Location: #loc#",
      "name": "John",
      "sname": "Doe",
      "loc": "LA"
    });
    

    想要使用string.replace(pattern, function) 的人也可能对此感兴趣。

    When did all browsers start supporting the String.replace(regexp, replacement_function)?

    【讨论】:

      【解决方案4】:
      myObj = {
          "strPattern": "Name: #subStr1#<br>Surname: #subStr2#<br>Location: #subStr3#",
          "subStr1": "John",
          "subStr2": "Doe",
          "subStr3": "LA"
      }
      function patternMatcher(myObj){
        strp = myObj.strPattern;
        pattern = strp.match(/#(.*?)#/g);
      
        for (key in pattern){
          origKey = pattern[key].substr(1,pattern[key].length-2);
          strp =  strp.replace(pattern[key],myObj[origKey])
        }
      return strp;
      }
      
      console.log(patternMatcher(myObj)); 
      

      这是你的代码运行示例link

      【讨论】:

        【解决方案5】:
        function getFilled(myObj){
          pattern = myObj.strPattern.match(/#(.*?)#/g);
          for (key in pattern){
            myObj.strPattern =  myObj.strPattern.replace(pattern[key],myObj[pattern[key].substr(1,pattern[key].length-2)])
          }
        return myObj.strPattern;
        }
        
        console.log(getFilled(myObj)); 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-25
          • 1970-01-01
          • 1970-01-01
          • 2014-10-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多