将多个字符串替换为多个其他字符串

2022-08-30 00:11:01

我正在尝试将字符串中的多个单词替换为多个其他单词。绳子是“我有一只猫,一只狗和一只山羊。

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

答案 1

具体解决方案

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

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 和所需替换的映射传递给函数,它就会返回转换后的字符串。

功能小提琴

为了确保Object.keys在较旧的浏览器中工作,请添加一个polyfill,例如来自MDNEs5


答案 2

作为以下问题的答案:

寻找最新的答案

如果像当前示例中那样使用“单词”,则可以使用非捕获组扩展 Ben McCormick 的答案,并在左侧和右侧添加单词边界以防止部分匹配。\b

\b(?:cathy|cat|catch)\b
  • \b用于防止部分匹配的单词边界
  • (?:非捕获组
    • cathy|cat|catch匹配其中一个替代方案
  • )关闭非捕获组
  • \b用于防止部分匹配的单词边界

原始问题的示例:

let str = "I have a cat, a dog, and a goat.";
const mapObj = {
  cat: "dog",
  dog: "goat",
  goat: "cat"
};
str = str.replace(/\b(?:cat|dog|goat)\b/gi, matched => mapObj[matched]);
console.log(str);

注释中似乎运行不正常的示例示例:

let str = "I have a cat, a catch, and a cathy.";
const mapObj = {
  cathy: "cat",
  cat: "catch",
  catch: "cathy"

};
str = str.replace(/\b(?:cathy|cat|catch)\b/gi, matched => mapObj[matched]);
console.log(str);