替换 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
Replacing Text Inside of Curley Braces JavaScript
提问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:
这是发生的事情:
- we are given a string with values in braces that need replaced
- a loop uses "replaceArray" to find all of the values in curly braces that will need replaced
- these values, along with the curly braces, will be replaced with the corresponding values in the "replaceWith" array
- 我们得到一个字符串,其中大括号中的值需要替换
- 循环使用“replaceArray”查找需要替换的花括号中的所有值
- 这些值以及花括号将被替换为“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.replace
is not destructive - it doesn't change the string itself, so you'll have to set myString = myString.replace(...)
. Second, you can create RegExp
objects 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.length
instead of i <= replaceArray.length - 1
to 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(/}/, '')];
});
}
回答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 的正则表达式的更多信息。