I\'m trying to replace multiple words in a string with multiple other words. The string is \"I have a cat, a dog, and a goat.\"
However, this does not produce \"I ha
All solutions work great, except when applied in programming languages that closures (e.g. Coda, Excel, Spreadsheet's REGEXREPLACE
).
Two original solutions of mine below use only 1 concatenation and 1 regex.
The idea is to append replacement values if they are not already in the string. Then, using a single regex, we perform all needed replacements:
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;
Explanations:
cat(?=[\s\S]*(dog))
means that we look for "cat". If it matches, then a forward lookup will capture "dog" as group 1, and "" otherwise."$1$2$3"
(the concatenation of all three groups), which will always be either "dog", "cat" or "goat" for one of the above casesstr+"||||cat,dog,goat"
, we remove them by also matching \|\|\|\|.*$
, in which case the replacement "$1$2$3"
will evaluate to "", the empty string.One problem with Method #1 is that it cannot exceed 9 replacements at a time, which is the maximum number of back-propagation groups. Method #2 states not to append just replacement values, but replacements directly:
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;
Explanations:
(str+"||||,cat=>dog,dog=>goat,goat=>cat")
is how we append a replacement map to the end of the string.(\b\w+\b)
states to "capture any word", that could be replaced by "(cat|dog|goat) or anything else.(?=[\s\S]*...)
is a forward lookup that will typically go to the end of the document until after the replacement map.
,\1=>
means "you should find the matched word between a comma and a right arrow"([^,]*)
means "match anything after this arrow until the next comma or the end of the doc"|\|\|\|\|.*$
is how we remove the replacement map.