我正在尝试用多个其他单词替换字符串中的多个单词。字符串是“我有一只猫,一只狗和一只山羊。”
然而,这并不产生“我有一只狗、一只山羊和一只猫”,而是产生“我有一只猫、一只猫和一只猫”。在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".
26条答案
按热度按时间iezvtpos1#
我修改了ben mccormick的答案,以便与您的新测试用例一起使用。
我只是在正则表达式中添加了单词边界:
“运行代码段”以查看以下结果:
fumotvh32#
使用jquery的解决方案(首先包括此文件):将多个字符串替换为多个其他字符串:
7kqas0il3#
我对@benmccormicks进行了一些扩展。他的方法适用于常规字符串,但如果我有转义字符或通配符,则不适用。这就是我所做的
返回“废话234433废话”
这样,它将匹配mapobj中的键,而不是匹配的单词
iyfamqjs4#
试试我的解决办法。随时改进
eit6fx6z5#
你可以试试这个。买东西不聪明。
我有一只狗,一只山羊和一只猫。
xdnvmnnf6#
一种可能的解决方案是使用mapper expression函数。
huus2vyu7#
我们还可以使用split()和join()方法:
jv2fixgn8#
所有的解决方案都非常有效,除非应用于那些需要闭包的编程语言(例如coda、excel、电子表格)
REGEXREPLACE
).下面我的两个原始解决方案仅使用1个串联和1个正则表达式。
方法#1:查找替换值
如果替换值不在字符串中,则添加替换值。然后,使用单个正则表达式执行所有需要的替换:
说明:
cat(?=[\s\S]*(dog))
意思是我们在找“猫”。如果匹配,则正向查找将捕获“dog”作为组1,否则捕获“”。第二组为捕捉“山羊”的“狗”,第三组为捕捉“猫”的“山羊”。
我们用
"$1$2$3"
(所有三组的串联),对于上述情况之一,始终为“狗”、“猫”或“山羊”如果我们手动向字符串添加替换项,如
str+"||||cat,dog,goat"
,我们也通过匹配来删除它们\|\|\|\|.*$
,在这种情况下,更换"$1$2$3"
将计算为“”的空字符串。方法2:查找替换对
方法#1的一个问题是一次不能超过9个替换,这是反向传播组的最大数量。方法#2声明不只是附加替换值,而是直接替换:
说明:
(str+"||||,cat=>dog,dog=>goat,goat=>cat")
是如何将替换Map附加到字符串的末尾。(\b\w+\b)
声明“捕获任何单词”,可以用“(猫|狗|山羊)或其他任何单词代替。(?=[\s\S]*...)
是一种正向查找,通常会一直到文档末尾,直到替换Map之后。,\1=>
表示“应该在逗号和右箭头之间找到匹配的单词”([^,]*)
表示“匹配此箭头后的任何内容,直到下一个逗号或文档结尾”|\|\|\|\|.*$
这是我们删除替换Map的方式。i2loujxw9#
通过使用prototype函数,我们可以很容易地通过向对象传递键和值以及可回放的文本来替换对象
disbfnqx10#
你可以用https://www.npmjs.com/package/union-replacer 为此目的。它基本上是一个
string.replace(regexp, ...)
对应项,允许在一个过程中发生多个替换,同时保留string.replace(...)
.披露:我是作者。开发该库是为了支持更复杂的用户可配置替换,它解决了所有问题,如捕获组、反向引用和回调函数替换。
不过,上面的解决方案对于精确的字符串替换来说已经足够好了。
x6h2sr2811#
我写了这个npm包https://www.npmjs.com/package/stringinject 它允许您执行以下操作
它将用数组项替换{0}和{1},并返回以下字符串
也可以使用对象键和值替换占位符,如下所示:
nkhmeac612#
dpiehjr413#
/*replacesome方法用于字符串,它接受我们想要的参数,并使用我们指定的最后一个参数替换所有参数。2013版权保存为:max ahmed这是一个示例:
jsfiddle:http://jsfiddle.net/cpj89/
oug3syen14#
作为对以下问题的答复:
正在寻找最新的答案
如果您在当前示例中使用“单词”,则可以使用非捕获组扩展ben mccormick的答案,并添加单词边界
\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);
nbnkbykc15#
注意!
如果您使用的是动态提供的Map,那么这里的任何解决方案都不够!
在这种情况下,有两种方法可以解决这个问题,(1)使用分割连接技术,(2)使用带有特殊字符转义技术的正则表达式。
这是一种拆分联接技术,比另一种快得多(至少快50%):
这是一种正则表达式特殊字符转义技术,它也可以工作,但速度要慢得多:
后者的优点是,它还可以用于不区分大小写的搜索。