使用占位符和替换对象格式化JavaScript字符串?

时间:2011-11-02 01:57:02

标签: javascript jquery string string-formatting

我有一个字符串,上面写着:My Name is %NAME% and my age is %AGE%.

%XXX%是占位符。我们需要从对象中替换值。

对象看起来像:{"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"}

我需要解析对象并用相应的值替换字符串。所以最终输出将是:

  

我的名字是迈克,我的年龄是26岁。

整个过程必须使用纯javascript或jquery来完成。

13 个答案:

答案 0 :(得分:96)

原始问题的要求显然无法受益于字符串插值,因为它似乎是任意替换键的运行时处理。

然而,如果您只需要进行字符串插值,则可以使用:

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

请注意分隔字符串的反引号,它们是必需的。


对于符合特定OP要求的答案,您可以使用String.prototype.replace()进行替换。

以下代码将处理所有匹配,而不是触摸没有替换的匹配(只要您的替换值是所有字符串,如果没有,请参阅下文)。

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

如果您的某些替换不是字符串,请确保它们首先存在于对象中。如果你有一个类似于示例的格式,即用百分号包裹,你可以使用in运算符来实现这一点。

jsFiddle

但是,如果您的格式没有特殊格式,即任何字符串,并且您的替换对象没有null原型,请使用Object.prototype.hasOwnProperty(),除非您可以保证不你的潜在替换子串将与原型上的属性名称冲突。

jsFiddle

否则,如果你的替换字符串是'hasOwnProperty',你就会得到一个混乱的字符串。

jsFiddle


作为旁注,您应该被称为replacementsObject,而不是Array

答案 1 :(得分:22)

如何使用ES6模板文字?

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

More about template literals...

答案 2 :(得分:11)

您可以使用JQuery(jquery.validate.js)使其轻松工作。

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

或者,如果您只想使用该功能,您可以定义该功能,并像

一样使用它
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"]));

归功于jquery.validate.js团队

答案 3 :(得分:7)

与现代浏览器一样,新版Chrome / Firefox支持占位符,类似于C样式函数printf()

<强>占位符:

  • %s字符串。
  • %d%i整数。
  • %f浮点数。
  • %o对象超链接。

<强> e.g。

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

BTW,看输出:

  • 在Chrome中,使用快捷方式Ctrl + Shift + JF12打开开发人员工具。
  • 在Firefox中,使用快捷方式Ctrl + Shift + K打开开发人员工具。 (请勿使用F12打开Firebug,而%f将不再维护,其控制台标签不会显示消息

@Update - nodejs支持

似乎nodejs不支持%d,而是可以在nodejs中使用%d<servlet> <servlet-name>StockServelt</servlet-name> <servlet-class>test.StockServelt</servlet-class> <init-param> <param-name>Premier</param-name> <param-value>/Premier</param-value> </init-param> <init-param> <param-name>Regular</param-name> <param-value>/Regular</param-value> </init-param> </servlet> 编号将打印为浮点数,而不仅仅是整数。

答案 4 :(得分:5)

当前,此行为在Javascript中仍然没有本地解决方案。 Tagged templates是相关的,但是不能解决。

这里有alex's solution的重构,其中有一个替换对象。

该解决方案使用箭头功能和类似的占位符语法作为本机Javascript interpolation in template literals{}而非{{1} })。另外,无需在分隔符名称中包含定界符%%)。

有两种口味(三种更新):描述性,简约性,优雅的简约感。

描述性解决方案:

%

精简解决方案:

const stringWithPlaceholders = 'My Name is {name} and my age is {age}.';

const replacements = {
  name: 'Mike',
  age: '26',
};

const string = stringWithPlaceholders.replace(
  /{\w+}/g,
  placeholderWithDelimiters => {
    const placeholderWithoutDelimiters = placeholderWithDelimiters.substring(
      1,
      placeholderWithDelimiters.length - 1,
    );
    const stringReplacement = replacements[placeholderWithoutDelimiters] || placeholderWithDelimiters;
    return stringReplacement;
  },
);

console.log(string);

UPDATE 2020-12-10

根据@Kade in the comments的建议,简化了带有组的解决方案:

const stringWithPlaceholders = 'My Name is {name} and my age is {age}.';

const replacements = {
  name: 'Mike',
  age: '26',
};

const string = stringWithPlaceholders.replace(/{\w+}/g, placeholder =>
  replacements[placeholder.substring(1, placeholder.length - 1)] || placeholder
);

console.log(string);

答案 5 :(得分:3)

只需使用replace()

即可
var values = {"%NAME%":"Mike","%AGE%":"26","%EVENT%":"20"};
var substitutedString = "My Name is %NAME% and my age is %AGE%.".replace("%NAME%", $values["%NAME%"]).replace("%AGE%", $values["%AGE%"]);

答案 6 :(得分:3)

您可以使用这样的自定义替换功能:

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);

你可以在这里看到它:http://jsfiddle.net/jfriend00/DyCwk/

答案 7 :(得分:1)

如果您想更接近console.log,例如替换

中的%s占位符
th:each="item : ${contact.phones}" th:text="${item.number}"

我写了这个

th:each="item : ${contact.phones}" th:text="${item.getNumber()}"
>console.log("Hello %s how are you %s is everything %s?", "Loreto", "today", "allright")
>Hello Loreto how are you today is everything allright?

你会得到

function log() {
  var args = Array.prototype.slice.call(arguments);
  var rep= args.slice(1, args.length);
  var i=0;
  var output = args[0].replace(/%s/g, function(match,idx) {
    var subst=rep.slice(i, ++i);
    return( subst );
  });
   return(output);
}
res=log("Hello %s how are you %s is everything %s?", "Loreto", "today", "allright");
document.getElementById("console").innerHTML=res;

<强>更新

我在处理字符串转换时添加了一个简单的变体<span id="console"/>,这就是它:

>log("Hello %s how are you %s is everything %s?", "Loreto", "today", "allright")
>"Hello Loreto how are you today is everything allright?"

在这种情况下,你会做

String.prototype

试用此版本here

答案 8 :(得分:1)

这可以让你做到这一点

NPM:https://www.npmjs.com/package/stringinject

GitHub:https://github.com/tjcafferkey/stringinject

通过执行以下操作:

var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });

// My username is tjcafferkey on Git

答案 9 :(得分:1)

这是通过在运行时动态使用es6模板文字来实现此目的的另一种方法。

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

答案 10 :(得分:0)

作为一个简单的例子:

// and you can see that I use the same builder
public String getString() {
    builder.delete(0, builder.length());
    char ascii;
    while (0 != (ascii = (char) getUByte()) && backing.hasRemaining())
        builder.append(ascii);
    return builder.toString();
}

输出结果为:

  

jack是40岁

答案 11 :(得分:0)

const stringInject = (str = '', obj = {}) => {
  let newStr = str;
  Object.keys(obj).forEach((key) => {
    let placeHolder = `#${key}#`;
    if(newStr.includes(placeHolder)) {
      newStr = newStr.replace(placeHolder, obj[key] || " ");
    }
  });
  return newStr;
}
Input: stringInject("Hi #name#, How are you?", {name: "Ram"});
Output: "Hi Ram, How are you?"

答案 12 :(得分:0)

我写了一个代码,可以轻松格式化字符串。

使用此功能。

function format() {
    if (arguments.length === 0) {
        throw "No arguments";
    }
    const string = arguments[0];
    const lst = string.split("{}");
    if (lst.length !== arguments.length) {
        throw "Placeholder format mismatched";
    }
    let string2 = "";
    let off = 1;
    for (let i = 0; i < lst.length; i++) {
        if (off < arguments.length) {
            string2 += lst[i] + arguments[off++]
        } else {
            string2 += lst[i]
        }
    }
    return string2;
}

示例

format('My Name is {} and my age is {}', 'Mike', 26);

输出

我的名字叫迈克,我的年龄是26岁