Javascript Replace - Dynamic Value of Replacement

后端 未结 7 1631
半阙折子戏
半阙折子戏 2020-12-21 10:58

I have a template in a String and I want to replace a few of the placeholders with the values that I have in another string. For every placeholder that I replace, I also wan

相关标签:
7条回答
  • 2020-12-21 11:03

    You could take the value with a check.

    template_html = template_html.replace(
        /#ADDRESS2#/g,
        val.address_2 && '<br />' + val.address_2
    );
    

    For more than one placeholder, you could take a dynamic approach and use same pattern for the search and replacements.

    var val = { address_2: 'foo', country_1: 'bar' }
        template_html = 'Address: #ADDRESS2#\nCountry: #COUNTRY1#\nnothing: #NOTHING#'
    
    template_html = template_html.replace(
        /#([^#]+)#/g,
        (_, group) => {
            var key = group.match(/^(\D+)(\d*)$/).slice(1).map(s => s.toLowerCase()).join('_');
    
            return (val[key] || '') && '<br />' + val[key];
         }
    );
    console.log(template_html);

    For getting a smarter replacement, yoou could take the idea of same strings as tempate and for getting the data from an object. In this case, take the replacement value and take this as key for the object or take an empty string for unknown values.

    var val = { ADDRESS2: 'foo', COUNTRY1: 'bar' }
        template_html = 'Address: #ADDRESS2#\nCountry: #COUNTRY1#\nnothing: #NOTHING#'
    
    template_html = template_html.replace(
        /#([^#]+)#/g,
        (_, key) => (val[key] || '') && '<br />' + val[key]
    );
    console.log(template_html);

    0 讨论(0)
  • 2020-12-21 11:06

    Perhaps you meant this?

    var val = {
      "address_1": "Address 1",
      "address_2": "",
      "address_10": "Address 10",
    }  
    var template_html = `My address is #ADDRESS1# delivery address is #ADDRESS2# and billing is #ADDRESS10#`
    template_html = template_html.replace(/#ADDRESS(\d+)#/g, function(addr, num) { 
      var str = val["address_"+num]; return str?str+"<br/>":""
    })
    console.log(template_html)

    0 讨论(0)
  • 2020-12-21 11:06

    If the same logic should be applied for multiple address fields, then you might benefit from a helper function:

    template_html = template_html
        .replace(/#CITY1#/g, PrefixBrIfNotEmpty(val.city_1))
        .replace(/#CITY2#/g, PrefixBrIfNotEmpty(val.city_2))
        .replace(/#CITY3#/g, PrefixBrIfNotEmpty(val.city_3))
        .replace(/#ADDRESS1#/g, PrefixBrIfNotEmpty(val.address_1))
        .replace(/#ADDRESS2#/g, PrefixBrIfNotEmpty(val.address_2))
        .replace(/#ADDRESS3#/g, PrefixBrIfNotEmpty(val.address_3));
    
    function PrefixBrIfNotEmpty(str) {
        return str ? '<br />' + str : '';
    }
    
    0 讨论(0)
  • 2020-12-21 11:09

    You can use ternary operator (empty string evaluates to false)

    template_html = template_html.replace(/#ADDRESS2#/g, val.address_2 ? '<br />'+ val.address_2 : '');
    
    0 讨论(0)
  • 2020-12-21 11:15

    Use a regex replacement, to which you pass a function.

    That function will get the replacement keys as input, and depending on if there's a replacement available, it will insert a empty string, or the replacement with a linebreak:

    const template = "#foo# this bla bla #bar# but #baz# and stuff";
    
    const replacements = {
      foo: "test",
      bar: "",
      baz: "not empty"
    };
    
    const result = template.replace(/#([^#]+)#/g, (match, key) => {
      // If there's a replacement for the key, return that replacement with a `<br />`. Otherwise, return a empty string.
      return replacements[key] !== undefined
        ? "<br />" + replacements[key]
        : "";
    });
    
    console.log("template:", template);
    console.log("result:", result);

    The only "gotcha" here is that the keys in the template string have to match the keys in your replacements object. That's not necessarily a bad thing, though, as it would make it slightly more intuitive if you'd look back at your code later on.

    The regex may look intimidating, but it's really quite simple:

    /#([^#]+)#/g

    • /: The start of the regex,
    • #: Literally the # character,
    • (: The start of a capturing group,
    • [^#]+ Any character that isn't a #. The + makes sure it matches as many as possible,
    • ): The end of a capturing group,
    • #: Literally the # character,
    • /g: The end of the regex. g is the global flag, so it doesn't stop at the first result.

    The capturing group basically tells the regex to group everything that's between the brackets. The groups are then returned individually.

    0 讨论(0)
  • 2020-12-21 11:15

    The simplest change is to use the ternary operator like this:

    template_html = template_html.replace(/#ADDRESS2#/g, ( val.address_2.length > 0 ) ? '<br />'+ val.address_2 : '');
    

    Still not particularly elegant but a bit shorter than the original.

    0 讨论(0)
提交回复
热议问题