我试图用多个其他单词替换字符串中的多个单词。字符串是“我有一只猫,一只狗和一只山羊。”
然而,这并不会产生“我有一只狗、一只山羊和一只猫”,而是产生“我有一只猫、一只猫和一只猫”。是否有可能在JavaScript中同时用多个其他字符串替换多个字符串,以便产生正确的结果?
var str = "I have a cat, a dog, and a goat.";
str = str.replace(/cat/gi, "dog");
str = str.replace(/dog/gi, "goat");
str = str.replace(/goat/gi, "cat");
//this produces "I have a cat, a cat, and a cat"
//but I wanted to produce the string "I have a dog, a goat, and a cat".
使用编号的物品,防止再次更换。
如
let str = "I have a %1, a %2, and a %3";
let pets = ["dog","cat", "goat"];
then
str.replace(/%(\d+)/g, (_, n) => pets[+n-1])
它的工作原理:-
%\d+查找跟在%后面的数字。括号表示数字。
这个数字(作为字符串)是lambda函数的第二个参数n。
+n-1将字符串转换为数字,然后减去1以索引宠物数组。
然后将%数字替换为数组下标处的字符串。
/g导致lambda函数被重复调用,每个数字被替换为数组中的字符串。
在现代JavaScript中:-
replace_n=(str,...ns)=>str.replace(/%(\d+)/g,(_,n)=>ns[n-1])
作为对以下问题的回答:
寻找最新的答案
如果在当前示例中使用“words”,则可以使用非捕获组扩展Ben McCormick的答案,并在左侧和右侧添加单词边界\b以防止部分匹配。
\b(?:cathy|cat|catch)\b
防止部分匹配的单词边界
(?:非捕获组
Cathy |cat|catch匹配其中一个选项
)关闭非捕获组
防止部分匹配的单词边界
原问题的例子:
let str = "我有一只猫,一只狗和一只山羊。";
const mapObj = {
猫:“狗”,
狗:“山羊”,
山羊:“猫”
};
str = str.replace(/\b(?:猫|狗|山羊)\b/gi, matched => mapObj[matched]);
console.log (str);
评论中的例子似乎并没有很好地工作:
let str = "I have a cat, a catch and a cathy.";
const mapObj = {
凯茜:“猫”,
猫:“抓”,
抓住:“凯蒂”
};
str = str.replace(/\b(?:cathy|cat|catch)\b/gi, matched => mapObj[matched]);
console.log (str);
具体的解决方案
您可以使用一个函数来替换每一个。
var str = "I have a cat, a dog, and a goat.";
var mapObj = {
cat:"dog",
dog:"goat",
goat:"cat"
};
str = str.replace(/cat|dog|goat/gi, function(matched){
return mapObj[matched];
});
jsfiddle例子
概括它
如果您想动态地维护正则表达式,并且只是将未来的交换添加到映射中,您可以这样做
new RegExp(Object.keys(mapObj).join("|"),"gi");
生成正则表达式。就像这样
var mapObj = {cat:"dog",dog:"goat",goat:"cat"};
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");
str = str.replace(re, function(matched){
return mapObj[matched];
});
要添加或更改任何替换,您只需编辑地图。
摆弄动态正则表达式
可重复使用
如果你想让它成为一般形式你可以把它变成这样一个函数
function replaceAll(str,mapObj){
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");
return str.replace(re, function(matched){
return mapObj[matched.toLowerCase()];
});
}
然后你可以把str和你想要的替换的映射传递给函数它会返回转换后的字符串。
摆弄函数
确保对象。key适用于旧的浏览器,添加一个填充,例如从MDN或Es5。
使用编号的物品,防止再次更换。
如
let str = "I have a %1, a %2, and a %3";
let pets = ["dog","cat", "goat"];
then
str.replace(/%(\d+)/g, (_, n) => pets[+n-1])
它的工作原理:-
%\d+查找跟在%后面的数字。括号表示数字。
这个数字(作为字符串)是lambda函数的第二个参数n。
+n-1将字符串转换为数字,然后减去1以索引宠物数组。
然后将%数字替换为数组下标处的字符串。
/g导致lambda函数被重复调用,每个数字被替换为数组中的字符串。
在现代JavaScript中:-
replace_n=(str,...ns)=>str.replace(/%(\d+)/g,(_,n)=>ns[n-1])
我写了这个npm包stringinject https://www.npmjs.com/package/stringinject,它允许你做以下事情
var string = stringInject("this is a {0} string for {1}", ["test", "stringInject"]);
这将替换{0}和{1}与数组项,并返回以下字符串
"this is a test string for stringInject"
或者你可以像这样用对象键和值替换占位符:
var str = stringInject("My username is {username} on {platform}", { username: "tjcafferkey", platform: "GitHub" });
"My username is tjcafferkey on Github"