替换Curley Braces JavaScript中的文本

Oli*_*ryn 14 javascript replace match curly-braces dynamic-variables

我正在尝试使用JavaScript来动态替换花括号内的内容.这是我的代码示例:

var myString = "This is {name}'s {adjective} {type} in JavaScript! Yes, a {type}!";
var replaceArray = ['name', 'adjective', 'type'];
var replaceWith = ['John', 'simple', 'string'];

for(var i = 0; i <= replaceArray.length - 1; i ++) {
  myString.replace(/\{replaceArray[i]\}/gi, replaceWith[i]);
}

alert(myString);
Run Code Online (Sandbox Code Playgroud)

上面的代码应该输出"这是John在JavaScript中的简单字符串!是的,一个字符串!".

这是发生的事情:

  1. 我们给出了一个字符串,其中包含需要替换的大括号中的值
  2. 循环使用"replaceArray"来查找需要替换的花括号中的所有值
  3. 这些值以及花括号将替换为"replaceWith"数组中的相应值

但是,我没有运气,特别是因为一个值可以在多个位置被替换,并且我在正则表达式中处理动态值.

任何人都可以帮我解决这个问题,使用与上面类似的设置吗?

Yi *_*ang 15

首先,String.replace它不是破坏性的 - 它不会改变字符串本身,所以你必须设置myString = myString.replace(...).其次,您可以RegExp动态创建对象new RegExp,因此所有结果都是:

var myString = "This is {name}'s {adjective} {type} in JavaScript! Yes, a {type}!",
    replaceArray = ['name', 'adjective', 'type'],
    replaceWith = ['John', 'simple', 'string'];

for(var i = 0; i < replaceArray.length; i++) {
    myString = myString.replace(new RegExp('{' + replaceArray[i] + '}', 'gi'), replaceWith[i]);
}
Run Code Online (Sandbox Code Playgroud)


aar*_*own 10

我发现做到这一点的最好方法是使用内联替换函数,就像其他人提到的那样,以及我从谁那里借来的。特别感谢 @yannic-hamann 的正则表达式和清晰的示例。我并不担心性能,因为我这样做只是为了构建路径。

我在MDN 的文档中找到了我的解决方案。

const interpolateUrl = (string, values) => string.replace(/{(.*?)}/g, (match, offset) => values[offset]);

const path = 'theresalways/{what}/inthe/{fruit}-stand/{who}';
const paths = {
  what: 'money',
  fruit: 'banana',
  who: 'michael',
};

const expected = 'theresalways/money/inthe/banana-stand/michael';

const url = interpolateUrl(path, paths);

console.log(`Is Equal: ${expected === url}`);
console.log(`URL: ${url}`)
Run Code Online (Sandbox Code Playgroud)


rsp*_*rsp 5

字符串是不可变的

JavaScript中的字符串是不可变的.这意味着这将永远不会像您期望的那样工作:

myString.replace(x, y);
alert(myString);
Run Code Online (Sandbox Code Playgroud)

这不仅仅是一个问题.replace()- 没有什么可以改变JavaScript中的字符串.你可以做的是:

myString = myString.replace(x, y);
alert(myString);
Run Code Online (Sandbox Code Playgroud)

正则表达式文字不会插值

JavaScript中的正则表达式文字不会插值,所以这仍然不起作用:

myString = myString.replace(/\{replaceArray[i]\}/gi, replaceWith[i]);
Run Code Online (Sandbox Code Playgroud)

你必须做这样的事情:

myString = myString.replace(new RegExp('\{'+replaceArray[i]+'\}', 'gi'), replaceWith[i]);
Run Code Online (Sandbox Code Playgroud)

但这有点乱,所以你可以先创建一个正则表列表:

var regexes = replaceArray.map(function (string) {
    return new RegExp('\{' + string + '\}', 'gi');
});
for(var i = 0; i < replaceArray.length; i ++) {
  myString = myString.replace(regexes[i], replaceWith[i]);
}
Run Code Online (Sandbox Code Playgroud)

如您所见,您也可以使用i < replaceArray.length而不是i <= replaceArray.length - 1简化循环条件.

2017年更新

现在你可以让它变得更简单:

var regexes = replaceArray.map(string => new RegExp(`\{${string}\}`, 'gi'));
for(var i = 0; i < replaceArray.length; i ++) {
  myString = myString.replace(regexes[i], replaceWith[i]);
}
Run Code Online (Sandbox Code Playgroud)

没有循环

而不是.replace()一遍又一遍地循环和应用函数,你只能这样做一次:

var mapping = {};
replaceArray.forEach((e,i) => mapping[`{${e}}`] = replaceWith[i]);
myString = myString.replace(/\{\w+\}/ig, n => mapping[n]);
Run Code Online (Sandbox Code Playgroud)

DEMO.

模板引擎

您基本上是在创建自己的模板引擎.如果您想使用现成的解决方案,请考虑使用:

或类似的东西.

使用Mustache尝试做的一个例子是:

var myString = "This is {{name}}'s {{adjective}} {{type}} in JavaScript! Yes, a {{type}}!";

var myData = {name: 'John', adjective: 'simple', type: 'string'};

myString = Mustache.to_html(myString, myData);

alert(myString);
Run Code Online (Sandbox Code Playgroud)

DEMO.