我试图用多个其他单词替换字符串中的多个单词。字符串是“我有一只猫,一只狗和一只山羊。”

然而,这并不会产生“我有一只狗、一只山羊和一只猫”,而是产生“我有一只猫、一只猫和一只猫”。是否有可能在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".

当前回答

以防有人想知道为什么原来海报上的解决方案不管用:

var str = "I have a cat, a dog, and a goat.";

str = str.replace(/cat/gi, "dog");
// now str = "I have a dog, a dog, and a goat."

str = str.replace(/dog/gi, "goat");
// now str = "I have a goat, a goat, and a goat."

str = str.replace(/goat/gi, "cat");
// now str = "I have a cat, a cat, and a cat."

其他回答

    var str = "I have a cat, a dog, and a goat.";

    str = str.replace(/goat/i, "cat");
    // now str = "I have a cat, a dog, and a cat."

    str = str.replace(/dog/i, "goat");
    // now str = "I have a cat, a goat, and a cat."

    str = str.replace(/cat/i, "dog");
    // now str = "I have a dog, a goat, and a cat."

我修改了本·麦考密克的答案以配合你的新测试用例。 我只是在正则表达式中添加了单词边界:

/\b(cathy|cat|catch)\b/gi

“运行代码片段”可以看到下面的结果:

var str = "我有一只猫,一个catch,和一个cathy."; var mapObj = { 凯茜:“猫”, 猫:“抓”, 抓住:“凯蒂” }; STR = STR .replace(/\b(cathy|cat|catch)\b/gi, function(matched){ 返回mapObj(匹配); }); console.log (str);

可以使用分隔符查找和替换字符串。

Var obj = { “firstname”:“约翰”, “姓”:“母鹿” } var文本= "你好{firstname},你的名字是{firstname}和姓氏是{lastname}" console.log (mutliStringReplace (obj、文本)) 函数mutliStringReplace(对象,字符串){ Var val =字符串 var entries = object .entries(object); entries.forEach ((para) = > { Var find = '{' + para[0] + '}' var regExp = new regExp (find,'g') val = val.replace(regExp, para[1]) }) 返回val; }

具体的解决方案

您可以使用一个函数来替换每一个。

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。

注意!

如果您正在使用动态提供的映射,这里的解决方案都不够!

在这种情况下,有两种解决方法:(1)使用分割连接技术,(2)使用正则表达式和特殊字符转义技术。

这是一个分割连接技术,它比另一个快得多(至少快50%):

var str = "I have {abc} a c|at, a d(og, and a g[oat] {1} {7} {11." var mapObj = { 'c|at': "d(og", 'd(og': "g[oat", 'g[oat]': "c|at", }; var entries = Object.entries(mapObj); console.log( entries .reduce( // Replace all the occurrences of the keys in the text into an index placholder using split-join (_str, [key], i) => _str.split(key).join(`{${i}}`), // Manipulate all exisitng index placeholder -like formats, in order to prevent confusion str.replace(/\{(?=\d+\})/g, '{-') ) // Replace all index placeholders to the desired replacement values .replace(/\{(\d+)\}/g, (_,i) => entries[i][1]) // Undo the manipulation of index placeholder -like formats .replace(/\{-(?=\d+\})/g, '{') );

这一个,是Regex特殊字符转义技术,它也有用,但慢得多:

var str = "I have a c|at, a d(og, and a g[oat]." var mapObj = { 'c|at': "d(og", 'd(og': "g[oat", 'g[oat]': "c|at", }; console.log( str.replace( new RegExp( // Convert the object to array of keys Object.keys(mapObj) // Escape any special characters in the search key .map(key => key.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')) // Create the Regex pattern .join('|'), // Additional flags can be used. Like `i` - case-insensitive search 'g' ), // For each key found, replace with the appropriate value match => mapObj[match] ) );

后者的优点是,它也可以用于不区分大小写的搜索。