2

I have a string prototype whose code is given below:

String.prototype.replaceAll = function(str1, str2, ignore) { 
  return this.replace(
    new RegExp(
      str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"
    ):str2
  )};

Usage:

var a = "I am Javascript";
console.log(
  a.replaceAll("am", "love")
); // => I love Javascript

But when it comes to multiple exchange of characters or words, I have to run the prototype multiple times to achieve it. But I have thought of something like this:

  var a = "I am Java";
  console.log(
    a.replaceAll(["am" , "Java"], ["love", "Javascript"])
  ); // => I love Javascript

So can you help me to achieve it? Or there is any other alternative?

2
  • Seems no way to replace all pairs the same time. Re-implements your function replaceAll as you think with One-by-one. Commented Dec 7, 2019 at 3:21
  • 3
    Does this answer your question? Replace multiple strings with multiple other strings. I should have looked for this dupe before answering (my mistake). Commented Dec 7, 2019 at 3:25

2 Answers 2

4

I'd prefer to store replacements as key-value pairs in an object or as an array of pairs. Regardless of the format, you can dynamically create a regex by joining the values you want to replace using | alternation. Then give replace a callback function and use its match parameter as a key to look up its corresponding pair in the swaps object.

const s = "I am Java";
const swaps = {am: "love", Java: "JS"};
const pattern = new RegExp(Object.keys(swaps).join("|"), "g");
console.log(s.replace(pattern, m => swaps[m]));

To handle case-insensitive replacements, ensure all keys in swaps are lowercase (either programmatically or manually, depending on usage) and lowercase the matches before keying in:

const s = "I am Java";
const swaps = {am: "love", java: "JS"};
const pattern = new RegExp(Object.keys(swaps).join("|"), "gi");
console.log(s.replace(pattern, m => swaps[m.toLowerCase()]));

Sign up to request clarification or add additional context in comments.

3 Comments

It seems as a good alternative to my replaceAll prototype.
You can certainly generalize this further, put it into a prototype if you wish and escape regex special characters as you're doing.
Thats great, thanks for the advice.
1

This works.

String.prototype.replaceAll = function(str1, str2, ignore) {

  let flags = 'g';
  if (ignore) {
    flags += 'i';
  }

  if (Array.isArray(str1) && Array.isArray(str2)) {
    let newStr = this;

    str1.map((element, index) => {
      if (str2[index]) {
        newStr = newStr.replace(new RegExp(element, flags), str2[index]);
      }
      return newStr;
    });
    return newStr;
  }
  else {
    return this.replace(new RegExp(str1, flags), str2);
  }
}

1 Comment

Note that if there are dependency chains this runs into trouble. For example, "a b".replaceAll(["a", "b"],["b", "c"]);, you might expect "b c" but doing the operations one by one gives you "c c" instead. It also prohibits replacing with empty strings because if (str2[index]) interprets them as falsey.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.