我正在尝试用多个其他单词替换字符串中的多个单词。字符串是“我有一只猫,一只狗和一只山羊。”
然而,这不会产生“我有一只狗,一只山羊和一只猫”,而是产生“我有一只猫,一只猫和一只猫”。是否可以在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".
答案 0 :(得分:345)
您可以使用函数替换每个函数。
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];
});
如果您想动态维护正则表达式并只是将未来的交换添加到地图中,则可以执行此操作
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和你想要的替换的映射传递给函数,它将返回转换后的字符串。
答案 1 :(得分:8)
在这种情况下,这可能无法满足您的确切需求,但我发现这是替换字符串中多个参数的有用方法,作为一般解决方案。它将替换参数的所有实例,无论它们被引用多少次:
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'
答案 2 :(得分:7)
作为回答:
<块引用>寻找最新的答案
如果您在当前示例中使用“单词”,您可以使用非捕获组扩展 Ben McCormick 的答案并在左侧和右侧添加单词边界 def count_matches(a, b):
return sum(x == y for x, y in zip(a, b))
以防止部分匹配。
\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);
答案 3 :(得分:4)
这对我有用:
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"
答案 4 :(得分:3)
使用编号项目以防止再次更换。 例如
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以索引pets数组。
然后将%编号替换为数组索引处的字符串。
/ g导致lambda函数被重复调用每个数字,然后用数组中的字符串替换。
在现代JavaScript中: -
replace_n=(str,...ns)=>str.replace(/%(\d+)/g,(_,n)=>ns[n-1])
答案 5 :(得分:2)
This solution 可以只替换整个词 - 例如,在搜索“cat”时不会找到“catch”、“ducat”或“locator” .这可以通过对正则表达式中每个单词前后的单词字符使用负后视 (?<!\w)
和负前瞻 (?!\w)
来完成:
(?<!\w)(cathy|cat|ducat|locator|catch)(?!\w)
JSFiddle 演示:http://jsfiddle.net/mfkv9r8g/1/
答案 6 :(得分:2)
用户常规函数定义要替换的模式,然后使用replace函数来处理输入字符串,
var i = new RegExp('"{','g'),
j = new RegExp('}"','g'),
k = data.replace(i,'{').replace(j,'}');
答案 7 :(得分:1)
以防万一有人想知道为什么原始海报的解决方案无效:
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."
答案 8 :(得分:1)
/\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);
答案 9 :(得分:1)
在这种情况下,有两种方法可以解决这个问题,(1) 使用 split-join 技术,(2) 使用带有特殊字符转义技术的 Regex。
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]
)
);
后者的优点是它也可以用于不区分大小写的搜索。
答案 10 :(得分:0)
试试我的解决方案。随时改进
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))
答案 11 :(得分:0)
你可以试试这个。买不聪明。
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);
答案 12 :(得分:0)
一种可能的解决方案是使用映射器表达式函数。
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.
答案 13 :(得分:0)
我们也可以使用 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);
答案 14 :(得分:0)
所有解决方案都可以很好地工作,除非应用于闭包的编程语言(例如Coda,Excel,电子表格的REGEXREPLACE
)。
下面的两个原始解决方案仅使用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"
的值为空字符串“”。 方法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)
声明“捕获任何单词”,可以用“(cat | dog | goat)或其他任何内容代替。” (?=[\s\S]*...)
是一种前向查找,通常会一直到文档末尾,直到替换映射之后。
,\1=>
的意思是“您应该在逗号和右箭头之间找到匹配的词” ([^,]*)
的意思是“匹配此箭头后的所有内容,直到下一个逗号或文档的末尾为止” |\|\|\|\|.*$
是我们移除替换地图的方式。答案 15 :(得分:0)
通过使用原型函数,我们可以通过将键,值和可替换文本传递给对象来轻松替换
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}'))
答案 16 :(得分:0)
您可以为此使用https://www.npmjs.com/package/union-replacer。它基本上是string.replace(regexp, ...)
的对应对象,它允许一次替换执行多次替换,同时保留string.replace(...)
的全部功能。
披露:我是作者。开发该库是为了支持更复杂的用户可配置替换,它解决了所有问题,例如捕获组,后向引用和回调函数替换。
尽管上述解决方案足以精确替换字符串。
答案 17 :(得分:0)
您可以使用定界符查找和替换字符串。
var obj = {
'firstname': 'John',
'lastname': 'Doe'
}
var text = "My firstname is {firstname} and my 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;
}
答案 18 :(得分:0)
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)
示例
// ///////////// 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
答案 19 :(得分:0)
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."
答案 20 :(得分:0)
使用我的replace-once包,您可以执行以下操作:
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.'
答案 21 :(得分:0)
我写了这个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"
答案 22 :(得分:0)
<!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=' ';}
if(x=='car'){return x='BMW'}
else{return x;}//must need
});
document.getElementById("demo").innerHTML = res;
}
</script>
</body>
</html>
答案 23 :(得分:0)
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 CopyRights保存: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/
答案 24 :(得分:-1)
使用Jquery用多个其他字符串替换多个字符串
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
for (int i = 0; i < GridView1.HeaderRow.Cells.Count; i++)
{
string strHeaderRow = GridView1.HeaderRow.Cells[i].Text;
if (strHeaderRow == "ID")
{
string strMktURL = "http://www.address.com";
HyperLink hlColumns = AddHyperLink(e.Row.Cells[i], strMktURL);
}
}
}
}
protected HyperLink AddHyperLink(TableCell cell, string strURL)
{
HyperLink hl = new HyperLink();
hl.Text = cell.Text;
hl.Font.Underline = true;
hl.Target = "_blank";
hl.NavigateUrl = strURL;
hl.Attributes.Add("style", "color:Black;");
cell.Controls.Add(hl);
return hl;
}
答案 25 :(得分:-1)
我在@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)
返回&#34; blah blah 234433 blah blah&#34;
这样它将匹配mapObj中的键,而不匹配匹配的单词&#39;