Skip to content
Advertisement

How to replace list of words with tag at multiple indexes in Javascript

I have a response of parent string which I have to modify and replace with the provided start and end indexes.

let parentString = 'rnManchester United wonrnManchester City lostrnLeeds United tied'

let replaceValues = 
    {value: 'Manchester United', startIndex: 2, endIndex: 19}
    {value: 'Manchester City', startIndex: 25, endIndex: 40}
    {value: 'Leeds United', startIndex: 47, endIndex: 59}

Expected Final Result:

enter image description here

I tried below approach but was not successful

replaceAt(input: string, index: number, replacement: string, source: string) {
    return (
      input.substring(0, index) +
      replacement +
      input.substring(index + source.length)
    );
  }

Usage:

replaceValues.forEach((replaceMatch: any) => {
        parentString =  this.replaceAt(
              parentString,
              replaceMatch.startIndex,
              "<span class='replace-text-{{i}}'>${replaceMatch.value}</span>",
              replaceMatch.value
            );

please ignore my example names couldn’t think anything more

Advertisement

Answer

EDIT: My previous answer did not account to duplicate and did not use your indexes, so here it is a more consistent answer:

Convert string to array to ease manipulation

const parentArray = Array.from(parentString)

Now we have an array of characters, i.e [" ", " ", "M", "a", "n", "c", "h", ...]

For each item in replaceValues we use splice on our newly created array. Splice acctepts 3 arguments:

  1. First argument is the start index where we want to splice the array.
  2. Second argument is how many items in the array will be deleted/replaced.
  3. Third argument is with what we want to replace the array portion.
let numberOfCharsReplaced = 0

replaceValues.forEach(item => {
  parentArray.splice(item.startIndex - numberOfCharsReplaced, item.endIndex - item.startIndex, `<span>${item.value}</span>`)
  numberOfCharsReplaced = numberOfCharsReplaced + item.endIndex - item.startIndex - 1
  console.log(parentArray, numberOfCharsReplaced)
})

That numberOfCharsReplaced is necessary because since we splice and replace, we need to take account of the number of chars that has been replaced, what I am saying is that when we replace the ‘Manchester United’ word that has 16 chars, we pass from 16 items in the array to only 1 big word (i.e "<span>Manchester United</span>") so we can’t rely on the startIndex of the next value only, we need to do some calculation. It’s easier in the code.

We get back our string by using .join(), telling to the join method with which character we want to join each character.

const replacedParentString = parentArray.join("");

If you still wish to have an array of html string, use the split and shift method indicated in the old answer

Please refer to MDN to read more about the methods used in this answer

splice join


OLD ANSWER

Use values to replace names with their ‘html’ equivalent within the parent string

replaceValues.forEach(item => {
  parentString = parentString.replace(item.value, `<span>${item.value}</span>`)
})

Now you have a string that is like this:

rn<span>Manchester United</span> wonrn<span>Manchester City</span> lostrn<span>Leeds United</span> tied

So now you may want this string as an array of html content

let contentsArray = parentString.split("rn")

Now we have this:

 [
  "",
  "<span>Manchester United</span> won",
  "<span>Manchester City</span> lost",
  "<span>Leeds United</span> tied"
 ] 

Finally if you want to get rid of that initial empty string just shift the array once

contentsArray.shift()
Advertisement