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

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

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

具体的解决方案

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

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 example . jsfiddle example

概括它

如果您想动态地维护正则表达式,并且只是将未来的交换添加到映射中,您可以这样做

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适用于旧的浏览器,添加一个polyfill,例如从中数Es5

在这个实例中,这可能不能满足您的确切需求,但我发现这是一种有用的方法,可以替换字符串中的多个参数,作为通用解决方案。它将替换参数的所有实例,无论它们被引用了多少次:

String.prototype.fmt = function (hash) {
var string = this, key; for (key in hash) string = string.replace(new RegExp('\\{' + key + '\\}', 'gm'), hash[key]); return string
}

你可以这样调用它:

var person = '{title} {first} {last}'.fmt({ title: 'Agent', first: 'Jack', last: 'Bauer' });
// person = 'Agent Jack Bauer'
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;
}
< p > / * 字符串的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/

我扩展了一下@本麦考密克斯。他的工作规则字符串,但不如果我转义字符或通配符。我是这么做的

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)

返回"blah blah 234433 blah blah"

这样它将匹配mapObj中的键,而不是匹配的单词'

这招对我很管用:

String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};


function replaceAll(str, map){
for(key in map){
str = str.replaceAll(key, map[key]);
}
return str;
}


//testing...
var str = "bat, ball, cat";
var map = {
'bat' : 'foo',
'ball' : 'boo',
'cat' : 'bar'
};
var new = replaceAll(str, map);
//result: "foo, boo, bar"
<!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>

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

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."

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

使用正则函数定义要替换的模式,然后使用replace函数处理输入字符串,

var i = new RegExp('"{','g'),
j = new RegExp('}"','g'),
k = data.replace(i,'{').replace(j,'}');

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

使用我的取代曾经包,你可以做以下事情:

const replaceOnce = require('replace-once')


var str = 'I have a cat, a dog, and a goat.'
var find = ['cat', 'dog', 'goat']
var replace = ['dog', 'goat', 'cat']
replaceOnce(str, find, replace, 'gi')
//=> 'I have a dog, a goat, and a cat.'

使用编号的物品,防止再次更换。 如< / p >

let str = "I have a %1, a %2, and a %3";
let pets = ["dog","cat", "goat"];

然后

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])
    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."

使用Array.prototype.reduce ():

const arrayOfObjects = [
{ plants: 'men' },
{ smart:'dumb' },
{ peace: 'war' }
]
const sentence = 'plants are smart'


arrayOfObjects.reduce(
(f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence
)


// as a reusable function
const replaceManyStr = (obj, sentence) => obj.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence)


const result = replaceManyStr(arrayOfObjects , sentence1)
< p >的例子
// /////////////    1. replacing using reduce and objects


// arrayOfObjects.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence)


// replaces the key in object with its value if found in the sentence
// doesn't break if words aren't found


// Example


const arrayOfObjects = [
{ plants: 'men' },
{ smart:'dumb' },
{ peace: 'war' }
]
const sentence1 = 'plants are smart'
const result1 = arrayOfObjects.reduce((f, s) => `${f}`.replace(Object.keys(s)[0], s[Object.keys(s)[0]]), sentence1)


console.log(result1)


// result1:
// men are dumb




// Extra: string insertion python style with an array of words and indexes


// usage


// arrayOfWords.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence)


// where arrayOfWords has words you want to insert in sentence


// Example


// replaces as many words in the sentence as are defined in the arrayOfWords
// use python type {0}, {1} etc notation


// five to replace
const sentence2 = '{0} is {1} and {2} are {3} every {5}'


// but four in array? doesn't break
const words2 = ['man','dumb','plants','smart']


// what happens ?
const result2 = words2.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence2)


console.log(result2)


// result2:
// man is dumb and plants are smart every {5}


// replaces as many words as are defined in the array
// three to replace
const sentence3 = '{0} is {1} and {2}'


// but five in array
const words3 = ['man','dumb','plant','smart']


// what happens ? doesn't break
const result3 = words3.reduce((f, s, i) => `${f}`.replace(`{${i}}`, s), sentence3)


console.log(result3)


// result3:
// man is dumb and plants

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

var obj = {
'firstname': 'John',
'lastname': 'Doe'
}


var text = "Hello {firstname}, Your firstname is {firstname} and lastname is {lastname}"


console.log(mutliStringReplace(obj,text))


function mutliStringReplace(object, string) {
var val = string
var entries = Object.entries(object);
entries.forEach((para)=> {
var find = '{' + para[0] + '}'
var regExp = new RegExp(find,'g')
val = val.replace(regExp, para[1])
})
return val;
}

你可以使用https://www.npmjs.com/package/union-replacer来实现这个目的。它基本上是string.replace(regexp, ...)对应的,它允许在一次传递中发生多次替换,同时保留string.replace(...)的全部功能。

披露:我是作者。开发这个库是为了支持更复杂的用户可配置替换,它解决了所有有问题的事情,比如捕获组、反向引用和回调函数替换。

上面的解决方案对于精确的字符串替换来说已经足够好了。

通过使用原型函数,我们可以通过传递对象的键和值以及可替换的文本轻松地进行替换

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}'))

所有解决方案都很好,除非应用于闭包的编程语言(例如Coda, Excel,电子表格的REGEXREPLACE)。

我下面的两个原始解决方案只使用1个连接和1个正则表达式。

方法#1:查找替换值

其思想是,如果替换值不在字符串中,则附加替换值。然后,使用一个regex,我们执行所有需要的替换:

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"作为第一组,和“;”;否则。
  • “狗”也是一样;这将捕获“山羊”;作为第二组,“山羊”;这将捕获&;cat&;第三组。
  • 我们用"$1$2$3"(所有三个组的连接)替换,它将始终是"dog", "cat"或“;goat"以上任何一种情况
  • 如果我们手动将替换项附加到字符串(如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")是将替换映射附加到字符串末尾的方法。
  • (\b\w+\b)表示“捕获任何单词”,可以被“猫|狗|山羊”或其他任何东西取代。
  • (?=[\s\S]*...)是一个正向查找,通常会到文档的末尾,直到替换映射之后。
    • ,\1=>表示“你应该在逗号和右箭头之间找到匹配的单词”;
    • ([^,]*)表示“匹配箭头之后的任何内容,直到下一个逗号或文档结束”;
  • |\|\|\|\|.*$是我们删除替换映射的方法。

注意!

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

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

  1. 这是一个分割连接技术,它比另一个快得多(至少快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, '{')
);

  1. 这一个,是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]
)
);

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

/\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);

我们也可以使用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);

作为对以下问题的回答:

寻找最新的答案

如果你使用&;words&;就像在你当前的例子中,你可以使用非捕获组扩展本·麦考密克的答案,并在左边和右边添加单词边界\b以防止部分匹配。

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

原问题的例子:

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

这个解决方案只能用来替换整个单词——例如,"catch", "ducat"或“;locator"在搜索“猫”时找不到。这可以通过对正则表达式中每个单词前后的单词字符使用负向后查找(?<!\w)和负向前查找(?!\w)来实现:

(?<!\w)(cathy|cat|ducat|locator|catch)(?!\w)

JSFiddle演示:http://jsfiddle.net/mfkv9r8g/1/

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

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.

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

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);
把: 我有一只狗,一只山羊和一只猫。

试试我的解决方案。请随意改进

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

const str = 'Thanks for contributing an answer to Stack Overflow!'
const substr = ['for', 'to']


function boldString(str, substr) {
let boldStr
boldStr = str
substr.map(e => {
const strRegExp = new RegExp(e, 'g');
boldStr= boldStr.replace(strRegExp, `<strong>${e}</strong>`);
}
)
return boldStr
}