替换 Curley 括号内的文本 JavaScript

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5334380/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 16:51:31  来源:igfitidea点击:

Replacing Text Inside of Curley Braces JavaScript

javascriptreplacematchcurly-bracesdynamic-variables

提问by Oliver Spryn

I am trying to use JavaScript to dynamically replace content inside of curly braces. Here is an example of my code:

我正在尝试使用 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);

The above code, should, output "This is John's simple string in JavaScript! Yes, a string!".

上面的代码应该输出“这是约翰在 JavaScript 中的简单字符串!是的,一个字符串!”。

Here is what happens:

这是发生的事情:

  1. we are given a string with values in braces that need replaced
  2. a loop uses "replaceArray" to find all of the values in curly braces that will need replaced
  3. these values, along with the curly braces, will be replaced with the corresponding values in the "replaceWith" array
  1. 我们得到一个字符串,其中大括号中的值需要替换
  2. 循环使用“replaceArray”查找需要替换的花括号中的所有值
  3. 这些值以及花括号将被替换为“replaceWith”数组中的相应值

However, I am not having any luck, especially since one value may be replaced in multiple locations, and that I am dealing a dynamic value inside of the regular expression.

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

Can anyone help me fix this, using a similar setup as above?

谁能帮我解决这个问题,使用与上面类似的设置?

回答by Yi Jiang

First, String.replaceis not destructive - it doesn't change the string itself, so you'll have to set myString = myString.replace(...). Second, you can create RegExpobjects dynamically with new RegExp, so the result of all that would be:

首先,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]);
}

回答by rsp

Strings are immutable

字符串是不可变的

Strings in JavaScript are immutable. It means that this will never work as you expect:

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

myString.replace(x, y);
alert(myString);

This is not just a problem with .replace()- nothing can mutate a string in JavaScript. What you can do instead is:

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

myString = myString.replace(x, y);
alert(myString);

Regex literals don't interpolate values

正则表达式文字不插入值

Regular expression literals in JavaScript don't interpolate values so this will still not work:

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

myString = myString.replace(/\{replaceArray[i]\}/gi, replaceWith[i]);

You have to do something like this instead:

你必须做这样的事情:

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

But this is a little bit messy, so you may create a list of regexes first:

但这有点混乱,因此您可以先创建一个正则表达式列表:

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

As you can see, you can also use i < replaceArray.lengthinstead of i <= replaceArray.length - 1to simplify your loop condition.

如您所见,您还可以使用i < replaceArray.length代替i <= replaceArray.length - 1来简化循环条件。

Update 2017

2017 年更新

Now you can make it even simpler:

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

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

Without a loop

没有循环

Instead of looping and applying .replace()function over and over again, you can do it only once like this:

.replace()您可以像这样只执行一次,而不是一遍又一遍地循环和应用函数:

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

See DEMO.

演示

Templating engines

模板引擎

You are basically creating your own templating engine. If you want to use a ready solution instead, then consider using:

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

or something like that.

或类似的东西。

An example of what you are trying to do using Mustache would be:

您尝试使用 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);

See DEMO.

演示

回答by inorganik

Here's a function that takes the string and an array of replacements. It's flexible enough to be re-used. The only catch is, you need to use numbers in your string instead of strings. e.g.,

这是一个接受字符串和替换数组的函数。它足够灵活,可以重复使用。唯一的问题是,您需要在字符串中使用数字而不是字符串。例如,

var myString = "This is {0}'s {1} {2} in JavaScript! Yes, a {2}!";



function personalizeString(string, replacementArray) {

    return string.replace(/({\d})/g, function(j) { 
        return replacementArray[j.replace(/{/, '').replace(/}/, '')];
    });
}

Demo: http://jsfiddle.net/4cfy7qvn/

演示:http: //jsfiddle.net/4cfy7qvn/

回答by aaronwbrown

The best way I have found to do this, is to use an in-line replace function like others have mentioned, and from whom I borrowed. Special shout out to @yannic-hamann for the regex and clear example. I am not worried about performance, as I am only doing this to construct paths.

我找到的最好的方法是使用像其他人提到的那样的内嵌替换函数,我从他那里借来的。特别向@yannic-hamann 大声喊出正则表达式和清晰的例子。我不担心性能,因为我这样做只是为了构建路径。

I found my solution in MDN's docs.

我在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}`)

回答by Yannic Hamann

I really like rsp's answer. Especially the 'Without a loop' section. Nonetheless, I find the code not that intuitive. I understand that this question comes from the two arrays scenario and that is more than 7 years old, but since this question appears as #1 on google when searching to replace a string with curly braces and the author asked for a similar setupI am tempted to provide another solution.

我真的很喜欢 rsp 的回答。尤其是“无循环”部分。尽管如此,我发现代码并不那么直观。我知道这个问题来自两个数组场景并且已经超过 7 年了,但是由于这个问题在搜索用花括号替换字符串时在 google 上显示为 #1 并且作者要求类似的设置,我很想提供另一种解决方案。

That being said, a copy and paste solution to play around with:

话虽如此,一个复制和粘贴解决方案可以玩:

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

var regex = /{(.*?)}/g;
myString.replace(regex, (m, c) => ({
    "name": "John",
    "adjective": "simple",
    "type": "string"
})[c.trim().toLowerCase()]);

This resourcereally helped me to build and understand the code above and to learn more about regex with JavaScript in general.

资源确实帮助我构建和理解了上面的代码,并从总体上了解了有关使用 JavaScript 的正则表达式的更多信息。