用多个其他字符串替换多个字符串

hc8w905p  于 2021-09-13  发布在  Java
关注(0)|答案(26)|浏览(577)

我正在尝试用多个其他单词替换字符串中的多个单词。字符串是“我有一只猫,一只狗和一只山羊。”
然而,这并不产生“我有一只狗、一只山羊和一只猫”,而是产生“我有一只猫、一只猫和一只猫”。在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".
iezvtpos

iezvtpos1#

我修改了ben mccormick的答案,以便与您的新测试用例一起使用。
我只是在正则表达式中添加了单词边界:

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

“运行代码段”以查看以下结果:

var str = "I have a cat, a catch, and a cathy.";
var mapObj = {
   cathy:"cat",
   cat:"catch",
   catch:"cathy"
};
str = str.replace(/\b(cathy|cat|catch)\b/gi, function(matched){
  return mapObj[matched];
});

console.log(str);
fumotvh3

fumotvh32#

使用jquery的解决方案(首先包括此文件):将多个字符串替换为多个其他字符串:

var replacetext = {
    "abc": "123",
    "def": "456"
    "ghi": "789"
};

$.each(replacetext, function(txtorig, txtnew) {
    $(".eng-to-urd").each(function() {
        $(this).text($(this).text().replace(txtorig, txtnew));
    });
});
7kqas0il

7kqas0il3#

我对@benmccormicks进行了一些扩展。他的方法适用于常规字符串,但如果我有转义字符或通配符,则不适用。这就是我所做的

str = "[curl] 6: blah blah 234433 blah blah";
mapObj = {'\\[curl] *': '', '\\d: *': ''};

function replaceAll (str, mapObj) {

    var arr = Object.keys(mapObj),
        re;

    $.each(arr, function (key, value) {
        re = new RegExp(value, "g");
        str = str.replace(re, function (matched) {
            return mapObj[value];
        });
    });

    return str;

}
replaceAll(str, mapObj)

返回“废话234433废话”
这样,它将匹配mapobj中的键,而不是匹配的单词

iyfamqjs

iyfamqjs4#

试试我的解决办法。随时改进

function multiReplace(strings, regex, replaces) {
  return str.replace(regex, function(x) {
    // check with replaces key to prevent error, if false it will return original value
    return Object.keys(replaces).includes(x) ? replaces[x] : x;
  });
}
var str = "I have a Cat, a dog, and a goat.";
//(json) use value to replace the key
var replaces = {
  'Cat': 'dog',
  'dog': 'goat',
  'goat': 'cat',
}
console.log(multiReplace(str, /Cat|dog|goat/g, replaces))
eit6fx6z

eit6fx6z5#

你可以试试这个。买东西不聪明。

var str = "I have a cat, a dog, and a goat.";
console.log(str);
str = str.replace(/cat/gi, "XXX");
console.log(str);
str = str.replace(/goat/gi, "cat");
console.log(str);
str = str.replace(/dog/gi, "goat");
console.log(str);
str = str.replace(/XXX/gi, "dog");              
console.log(str);

我有一只狗,一只山羊和一只猫。

xdnvmnnf

xdnvmnnf6#

一种可能的解决方案是使用mapper expression函数。

const regex = /(?:cat|dog|goat)/gmi;
const str = `I have a cat, a dog, and a goat.`;

let mapper = (key) => {
  switch (key) {
    case "cat":
      return "dog"
    case "dog":
      return "goat";
    case "goat":
      return "cat"
  }
}
let result = str.replace(regex, mapper);

console.log('Substitution result: ', result);
//Substitution result1:  I have a dog, a goat, and a cat.
huus2vyu

huus2vyu7#

我们还可以使用split()和join()方法:

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

str=str.split("cat").map(x => {return x.split("dog").map(y => {return y.split("goat").join("cat");}).join("goat");}).join("dog");

console.log(str);
jv2fixgn

jv2fixgn8#

所有的解决方案都非常有效,除非应用于那些需要闭包的编程语言(例如coda、excel、电子表格) REGEXREPLACE ).
下面我的两个原始解决方案仅使用1个串联和1个正则表达式。

方法#1:查找替换值

如果替换值不在字符串中,则添加替换值。然后,使用单个正则表达式执行所有需要的替换:

var str = "I have a cat, a dog, and a goat.";
str = (str+"||||cat,dog,goat").replace(
   /cat(?=[\s\S]*(dog))|dog(?=[\s\S]*(goat))|goat(?=[\s\S]*(cat))|\|\|\|\|.*$/gi, "$1$2$3");
document.body.innerHTML = str;

说明: cat(?=[\s\S]*(dog)) 意思是我们在找“猫”。如果匹配,则正向查找将捕获“dog”作为组1,否则捕获“”。
第二组为捕捉“山羊”的“狗”,第三组为捕捉“猫”的“山羊”。
我们用 "$1$2$3" (所有三组的串联),对于上述情况之一,始终为“狗”、“猫”或“山羊”
如果我们手动向字符串添加替换项,如 str+"||||cat,dog,goat" ,我们也通过匹配来删除它们 \|\|\|\|.*$ ,在这种情况下,更换 "$1$2$3" 将计算为“”的空字符串。

方法2:查找替换对

方法#1的一个问题是一次不能超过9个替换,这是反向传播组的最大数量。方法#2声明不只是附加替换值,而是直接替换:

var str = "I have a cat, a dog, and a goat.";
str = (str+"||||,cat=>dog,dog=>goat,goat=>cat").replace(
   /(\b\w+\b)(?=[\s\S]*,\1=>([^,]*))|\|\|\|\|.*$/gi, "$2");
document.body.innerHTML = str;

说明: (str+"||||,cat=>dog,dog=>goat,goat=>cat") 是如何将替换Map附加到字符串的末尾。 (\b\w+\b) 声明“捕获任何单词”,可以用“(猫|狗|山羊)或其他任何单词代替。 (?=[\s\S]*...) 是一种正向查找,通常会一直到文档末尾,直到替换Map之后。 ,\1=> 表示“应该在逗号和右箭头之间找到匹配的单词” ([^,]*) 表示“匹配此箭头后的任何内容,直到下一个逗号或文档结尾” |\|\|\|\|.*$ 这是我们删除替换Map的方式。

i2loujxw

i2loujxw9#

通过使用prototype函数,我们可以很容易地通过向对象传递键和值以及可回放的文本来替换对象

String.prototype.replaceAll=function(obj,keydata='key'){
 const keys=keydata.split('key');
 return Object.entries(obj).reduce((a,[key,val])=> a.replace(`${keys[0]}${key}${keys[1]}`,val),this)
}

const data='hids dv sdc sd ${yathin} ${ok}'
console.log(data.replaceAll({yathin:12,ok:'hi'},'${key}'))
disbfnqx

disbfnqx10#

你可以用https://www.npmjs.com/package/union-replacer 为此目的。它基本上是一个 string.replace(regexp, ...) 对应项,允许在一个过程中发生多个替换,同时保留 string.replace(...) .
披露:我是作者。开发该库是为了支持更复杂的用户可配置替换,它解决了所有问题,如捕获组、反向引用和回调函数替换。
不过,上面的解决方案对于精确的字符串替换来说已经足够好了。

x6h2sr28

x6h2sr2811#

我写了这个npm包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"
nkhmeac6

nkhmeac612#

<!DOCTYPE html>
<html>
<body>

<p id="demo">Mr Blue 
has a           blue house and a blue car.</p>

<button onclick="myFunction()">Try it</button>

<script>
function myFunction() {
    var str = document.getElementById("demo").innerHTML;
    var res = str.replace(/\n| |car/gi, function myFunction(x){

if(x=='\n'){return x='<br>';}
if(x==' '){return x='&nbsp';}
if(x=='car'){return x='BMW'}
else{return x;}//must need

});

    document.getElementById("demo").innerHTML = res;
}
</script>

</body>
</html>
dpiehjr4

dpiehjr413#

String.prototype.replaceSome = function() {
    var replaceWith = Array.prototype.pop.apply(arguments),
        i = 0,
        r = this,
        l = arguments.length;
    for (;i<l;i++) {
        r = r.replace(arguments[i],replaceWith);
    }
    return r;
}

/*replacesome方法用于字符串,它接受我们想要的参数,并使用我们指定的最后一个参数替换所有参数。2013版权保存为:max ahmed这是一个示例:

var string = "[hello i want to 'replace x' with eat]";
var replaced = string.replaceSome("]","[","'replace x' with","");
document.write(string + "<br>" + replaced); // returns hello i want to eat (without brackets)
  • /

jsfiddle:http://jsfiddle.net/cpj89/

oug3syen

oug3syen14#

作为对以下问题的答复:
正在寻找最新的答案
如果您在当前示例中使用“单词”,则可以使用非捕获组扩展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);

nbnkbykc

nbnkbykc15#

注意!

如果您使用的是动态提供的Map,那么这里的任何解决方案都不够!

在这种情况下,有两种方法可以解决这个问题,(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, '{')
);

这是一种正则表达式特殊字符转义技术,它也可以工作,但速度要慢得多:

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

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

相关问题