Home > Software design >  String replace between two given indexes in multiple places of the string with JavaScript
String replace between two given indexes in multiple places of the string with JavaScript

Time:04-13

I have a string and an array of start and end indexes in the string which need to be replaced with some other content. For example, the input string is like follows:

Mention 1, Mention 3 and no more mentions.

And the array of indexes to be replaced is as follows:

[
  {
     start: 0,
     end: 8
  },
  {
     start: 11;
     end: 18
  }
]

Basically this should result in a string where the Mention 1 and Mention 3 are wrapped in an anchor (link).

I have found some examples like this one:

String.prototype.replaceBetween = function(start, end, what) {
  return this.substring(0, start)   what   this.substring(end);
};

console.log("The Hello World Code!".replaceBetween(4, 9, "Hi"));

However the problem with this implementation is that it's good only if there's 1 only place to replace, in my case there can be multiple places to be replaced. After the first replace the indexes for the rest will be shifted as the string will now contain also .

Any hint/clue would be much appreciated.

CodePudding user response:

EDIT: There are 2 questions here, as your example doesn't really cover the wrapping.

Using indexes, as you mention, each replacement shifts the position of all elements after the replacement. However, the indexes of characters before it would remain unchanged. You would simply need to iterate them in reverse.

var str = 'Mention 1, Mention 3 and no more mentions.'
for (const { start, end } of positions.reverse()) {
  str = str.replaceBetween(start, end, 'REPLACEMENT')
}

This doesn't really address the wrapping concern, though. If you actually must use array indices, the above could be changed to accept a function, e.g.:

String.prototype.replaceBetween = function (start, end, replacer) {
  const what = replacer(this.substring(start, end));
  return this.substring(0, start)   what   this.substring(end);
};

for (const { start, end } of positions.reverse()) {
  str = str.replaceBetween(start, end, (match) => `<a href="#">${match}</a>`);
}

If the indexes array is just an artifact of searching for a particular pattern, though, a cleaner solution could leverage String#replace with a regex and a replacer function

// the `/g` at the end means "global", so it will replace all matches
const pattern = /Mention \d /g;

var str = 'Mention 1, Mention 3 and no more mentions.'
str = str.replace(/Mention \d /g, (match) => {
  return `<a href="#">${match}</a>`;
});

Output: '<a href="#">Mention 1</a>, <a href="#">Mention 3</a> and no more mentions.'

CodePudding user response:

You must loop over your position array. Like that:

const n = [
  {
     start: 0,
     end: 8
  },
  {
     start: 11,
     end: 18
  }
];

let str = 'Mention 1, Mention 3 and no more mentions.';

String.prototype.replaceBetween = function(start, end, what) {
  return this.substring(0, start)   what   this.substring(end);
};

n.forEach(e => {  
  console.log("The Hello World Code!".replaceBetween(e.start, e.end, "Hi"));  
})

  • Related