Format a JavaScript string using placeholders and an object of substitutions?

前端 未结 13 2002
轻奢々
轻奢々 2020-12-07 10:56

I have a string with say: My Name is %NAME% and my age is %AGE%.

%XXX% are placeholders. We need to substitute values there from an object.

相关标签:
13条回答
  • 2020-12-07 11:28

    You can use a custom replace function like this:

    var str = "My Name is %NAME% and my age is %AGE%.";
    var replaceData = {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"};
    
    function substitute(str, data) {
        var output = str.replace(/%[^%]+%/g, function(match) {
            if (match in data) {
                return(data[match]);
            } else {
                return("");
            }
        });
        return(output);
    }
    
    var output = substitute(str, replaceData);
    

    You can see it work here: http://jsfiddle.net/jfriend00/DyCwk/.

    0 讨论(0)
  • 2020-12-07 11:28

    Here is another way of doing this by using es6 template literals dynamically at runtime.

    const str = 'My name is ${name} and my age is ${age}.'
    const obj = {name:'Simon', age:'33'}
    
    
    const result = new Function('const {' + Object.keys(obj).join(',') + '} = this.obj;return `' + str + '`').call({obj})
    
    document.body.innerHTML = result

    0 讨论(0)
  • 2020-12-07 11:33

    The requirements of the original question clearly couldn't benefit from string interpolation, as it seems like it's a runtime processing of arbitrary replacement keys.

    However, if you just had to do string interpolation, you can use:

    const str = `My name is ${replacements.name} and my age is ${replacements.age}.`
    

    Note the backticks delimiting the string, they are required.


    For an answer suiting the particular OP's requirement, you could use String.prototype.replace() for the replacements.

    The following code will handle all matches and not touch ones without a replacement (so long as your replacement values are all strings, if not, see below).

    var replacements = {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"},
        str = 'My Name is %NAME% and my age is %AGE%.';
    
    str = str.replace(/%\w+%/g, function(all) {
       return replacements[all] || all;
    });
    

    jsFiddle.

    If some of your replacements are not strings, be sure they exists in the object first. If you have a format like the example, i.e. wrapped in percentage signs, you can use the in operator to achieve this.

    jsFiddle.

    However, if your format doesn't have a special format, i.e. any string, and your replacements object doesn't have a null prototype, use Object.prototype.hasOwnProperty(), unless you can guarantee that none of your potential replaced substrings will clash with property names on the prototype.

    jsFiddle.

    Otherwise, if your replacement string was 'hasOwnProperty', you would get a resultant messed up string.

    jsFiddle.


    As a side note, you should be called replacements an Object, not an Array.

    0 讨论(0)
  • 2020-12-07 11:34

    How about using ES6 template literals?

    var a = "cat";
    var b = "fat";
    console.log(`my ${a} is ${b}`); //notice back-ticked string
    

    More about template literals...

    0 讨论(0)
  • 2020-12-07 11:34

    As with modern browser, placeholder is supported by new version of Chrome / Firefox, similar as the C style function printf().

    Placeholders:

    • %s String.
    • %d,%i Integer number.
    • %f Floating point number.
    • %o Object hyperlink.

    e.g.

    console.log("generation 0:\t%f, %f, %f", a1a1, a1a2, a2a2);
    

    BTW, to see the output:

    • In Chrome, use shortcut Ctrl + Shift + J or F12 to open developer tool.
    • In Firefox, use shortcut Ctrl + Shift + K or F12 to open developer tool.

    @Update - nodejs support

    Seems nodejs don't support %f, instead, could use %d in nodejs. With %d number will be printed as floating number, not just integer.

    0 讨论(0)
  • 2020-12-07 11:36

    You can use JQuery(jquery.validate.js) to make it work easily.

    $.validator.format("My name is {0}, I'm {1} years old",["Bob","23"]);
    

    Or if you want to use just that feature you can define that function and just use it like

    function format(source, params) {
        $.each(params,function (i, n) {
            source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
        })
        return source;
    }
    alert(format("{0} is a {1}", ["Michael", "Guy"]));
    

    credit to jquery.validate.js team

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