Specific Solution
You can use a function to replace each one.
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
Generalizing it
If you want to dynamically maintain the regex and just add future exchanges to the map, you can do this
new RegExp(Object.keys(mapObj).join("|"),"gi");
to generate the regex. So then it would look like this
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];
});
And to add or change any more replacements you could just edit the map.
fiddle with dynamic regex
Making it Reusable
If you want this to be a general pattern you could pull this out to a function like this
function replaceAll(str,mapObj){
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");
return str.replace(re, function(matched){
return mapObj[matched.toLowerCase()];
});
}
So then you could just pass the str and a map of the replacements you want to the function and it would return the transformed string.
fiddle with function
To ensure Object.keys works in older browsers, add a polyfill eg from MDN or Es5.
Answer from Ben McCormick on Stack OverflowSpecific Solution
You can use a function to replace each one.
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
Generalizing it
If you want to dynamically maintain the regex and just add future exchanges to the map, you can do this
new RegExp(Object.keys(mapObj).join("|"),"gi");
to generate the regex. So then it would look like this
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];
});
And to add or change any more replacements you could just edit the map.
fiddle with dynamic regex
Making it Reusable
If you want this to be a general pattern you could pull this out to a function like this
function replaceAll(str,mapObj){
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");
return str.replace(re, function(matched){
return mapObj[matched.toLowerCase()];
});
}
So then you could just pass the str and a map of the replacements you want to the function and it would return the transformed string.
fiddle with function
To ensure Object.keys works in older browsers, add a polyfill eg from MDN or Es5.
As an answer to:
looking for an up-to-date answer
If you are using "words" as in your current example, you might extend the answer of Ben McCormick using a non capture group and add word boundaries \b at the left and at the right to prevent partial matches.
\b(?:cathy|cat|catch)\b
\bA word boundary to prevent a partial match(?:Non capture groupcathy|cat|catchmatch one of the alternatives
)Close non capture group\bA word boundary to prevent a partial match
Example for the original question:
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);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Example for the example in the comments that not seems to be working well:
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);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
javascript - Replace multiple characters in one replace call - Stack Overflow
javascript - Replace multiple strings at once - Stack Overflow
javascript - How do I replace multiple items in a string? - Stack Overflow
string - Javascript Value Replace for Multiple Values - Stack Overflow
Use the OR operator (|):
var str = '#this #is__ __#a test###__';
console.log(
str.replace(/#|_/g, '') // "this is a test"
)
Run code snippetEdit code snippet Hide Results Copy to answer Expand
You could also use a character class:
str.replace(/[#_]/g,'');
Fiddle
If you want to replace the hash with one thing and the underscore with another, then you will just have to chain
function allReplace(str, obj) {
for (const x in obj) {
str = str.replace(new RegExp(x, 'g'), obj[x]);
}
return str;
};
console.log(
allReplace( 'abcd-abcd', { 'a': 'h', 'b': 'o' } ) // 'hocd-hocd'
);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Why not chain, though? I see nothing wrong with that.
If you want to replace multiple characters you can call the String.prototype.replace() with the replacement argument being a function that gets called for each match. All you need is an object representing the character mapping that you will use in that function.
For example, if you want a replaced with x, b with y, and c with z, you can do something like this:
const chars = {
'a': 'x',
'b': 'y',
'c': 'z'
};
let s = '234abc567bbbbac';
s = s.replace(/[abc]/g, m => chars[m]);
console.log(s);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Output: 234xyz567yyyyxz
You could extend the String object with your own function that does what you need (useful if there's ever missing functionality):
String.prototype.replaceArray = function(find, replace) {
var replaceString = this;
for (var i = 0; i < find.length; i++) {
replaceString = replaceString.replace(find[i], replace[i]);
}
return replaceString;
};
For global replace you could use regex:
String.prototype.replaceArray = function(find, replace) {
var replaceString = this;
var regex;
for (var i = 0; i < find.length; i++) {
regex = new RegExp(find[i], "g");
replaceString = replaceString.replace(regex, replace[i]);
}
return replaceString;
};
To use the function it'd be similar to your PHP example:
var textarea = $(this).val();
var find = ["<", ">", "\n"];
var replace = ["<", ">", "<br/>"];
textarea = textarea.replaceArray(find, replace);
Common Mistake
Nearly all answers on this page use cumulative replacement and thus suffer the same flaw where replacement strings are themselves subject to replacement. Here are a couple examples where this pattern fails (h/t @KurokiKaze @derekdreery):
function replaceCumulative(str, find, replace) {
for (var i = 0; i < find.length; i++)
str = str.replace(new RegExp(find[i],"g"), replace[i]);
return str;
};
// Fails in some cases:
console.log( replaceCumulative( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceCumulative( "you & me", ['you','me'], ['me','you'] ) );
Solution
function replaceBulk( str, findArray, replaceArray ){
var i, regex = [], map = {};
for( i=0; i<findArray.length; i++ ){
regex.push( findArray[i].replace(/([-[\]{}()*+?.\\^$|#,])/g,'\\$1') );
map[findArray[i]] = replaceArray[i];
}
regex = regex.join('|');
str = str.replace( new RegExp( regex, 'g' ), function(matched){
return map[matched];
});
return str;
}
// Test:
console.log( replaceBulk( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceBulk( "you & me", ['you','me'], ['me','you'] ) );
Note:
This is a more compatible variation of @elchininet's solution, which uses map() and Array.indexOf() and thus won't work in IE8 and older.
@elchininet's implementation holds truer to PHP's str_replace(), because it also allows strings as find/replace parameters, and will use the first find array match if there are duplicates (my version will use the last). I didn't accept strings in this implementation because that case is already handled by JS's built-in String.replace().
Use this expression:
var str = 'I like [dogs], [cats], and [birds]';
alert(str.replace(/\[(.+?)\]/g, '<a href="#">$1</a>'));
\[(.+?)\]asks for a literal[, to lazily match and capture anything, then to match a literal]. Replace with the captured stuff enclosed in<a>tags.The
gmodifier means global replacement, i.e. find and replace every match and not just the first.
jsFiddle preview
It's a simple string replace.
function tagIt(source)
{
return source.replace('[', '<a href="#">').replace(']', '</a>');
}