Replace multiple strings with multiple other strin

2018-12-31 18:27发布

问题:

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 have a dog, a goat, and a cat\", but instead it produces \"I have a cat, a cat, and a cat\". Is it possible to replace multiple strings with multiple other strings at the same time in JavaScript, so that the correct result will be produced?

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

回答1:

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.



回答2:

This may not meet your exact need in this instance, but I\'ve found this a useful way to replace multiple parameters in strings, as a general solution. It will replace all instances of the parameters, no matter how many times they are referenced:

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

You would invoke it as follows:

var person = \'{title} {first} {last}\'.fmt({ title: \'Agent\', first: \'Jack\', last: \'Bauer\' });
// person = \'Agent Jack Bauer\'


回答3:

This worked for me:

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:

user regular function to define the pattern to replace and then use replace function to work on input string,

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


回答5:

Use numbered items to prevent replacing again. eg

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

then

str.replace(/%(\\d+)/g, (_, n) => pets[+n-1])

How it works:- %\\d+ finds the numbers which come after a %. The brackets capture the number.

This number (as a string) is the 2nd parameter, n, to the lambda function.

The +n-1 converts the string to the number then 1 is subtracted to index the pets array.

The %number is then replaced with the string at the array index.

The /g causes the lambda function to be called repeatedly with each number which is then replaced with a string from the array.

In modern JavaScript:-

replace_n=(str,...ns)=>str.replace(/%(\\d+)/g,(_,n)=>ns[n-1])


回答6:

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 method for strings it takes as ,much arguments as we want and replaces all of them with the last argument we specified 2013 CopyRights saved for: Max Ahmed this is an example:

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/



回答7:

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


回答8:

Just in case someone is wondering why the original poster\'s solution is not working:

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


回答9:

I wrote this npm package stringinject https://www.npmjs.com/package/stringinject which allows you to do the following

var string = stringInject(\"this is a {0} string for {1}\", [\"test\", \"stringInject\"]);

which will replace the {0} and {1} with the array items and return the following string

\"this is a test string for stringInject\"

or you could replace placeholders with object keys and values like so:

var str = stringInject(\"My username is {username} on {platform}\", { username: \"tjcafferkey\", platform: \"GitHub\" });

\"My username is tjcafferkey on Github\" 


回答10:

With my replace-once package, you could do the following:

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.\'


回答11:

I expanded on @BenMcCormicks a bit. His worked for regular strings but not if I had escaped characters or wildcards. Here\'s what I did

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)

returns \"blah blah 234433 blah blah\"

This way it will match the key in the mapObj and not the matched word\'



回答12:

Using Jquery Replace multiple strings with multiple other strings

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