Replace string globally using veriable

Viewed 102

I'm trying to replace string globally using the variable, but getting an unexpected replacement while replacing it. I've searched the same issue but didn't get any solutions so I'm posting it here. Maybe you guys will lead me where I'm doing a mistake.

Here is the case:

  1. I have an HTML mail body and a list of links that I've extracted from the mail body and stored it as an array.
  2. I'm trying to iterate the links array and try to find the match from the mail body.
  3. And when I'm using the replace() method to replace the link by adding some prefix.

Looks pretty straight forward, right?

Here is the issue I'm getting while replacing the links.

There are some repeated links I've. While trying to replace them with the prefix, it is getting replace 2 times.

for e.x.

prefix = 'http://this.prefix?redirect_uri='
link = 'http://google.com'

// Expected Output
http://this.prefix?redirect_uri=http://google.com

// Getting Output
http://this.prefix?redirect_uri=http://this.prefix?redirect_uri=http://google.com

You can see the prefix is getting repeated.

I'm sharing my actual code, So, it will be more helpful to you guys to understand what I mean to say.


let mailBody = `
<div dir="auto">
  <a href="https://aabc.pagerduty.com/incidents">aabc.pagerduty.com</a>
  <a href="https://aabc.pagerduty.com/incidents/P9X3024">[FIRING:1] TooManyContainerRestarts (http 10.0.95.123:8080 kube-state-metrics newton newton/prometheus-operator-prometheus prometheus-operator-kube-state-metrics infra critical) </a></p>
  <a href="https://aabc.pagerduty.com/incidents/P9X3024">View Incident</a>
  <p>URGENCY </p>
</div>
`;

const links = [
  'https://aabc.pagerduty.com/incidents',
  'https://aabc.pagerduty.com/incidents/P9X3024'
]

const processTrackingLinks = (linkArray, mailBody) => {
  const prefix = 'https://test.io?redirect_uri=';
  // const mapping = [];
  for (let i=0; i < linkArray.length; i++){
    const replacer = new RegExp(linkArray[i], 'g')
    mailBody = mailBody.replace(replacer, prefix + linkArray[i]);
  }

  return mailBody;
};

mailBody = processTrackingLinks(links, mailBody);

console.log(mailBody);

If you have any idea why it is happening, Am I doing something wrong or it is an issue just let me know.

Any resolution will be appreciated. :)

2 Answers

How about this approach. You don't need the links array anymore.

const process = mailBody => {
    return mailBody.replace(/href="/g, `href="http://test.io?redirect_uri=`)
}

The problem lies in the links array you are using. Double replacement is due to the fact that "https://abc.pagerduty.com/incidents" is a substring of "https://abc.pagerduty.com/incidents/".

Use the following array instead:

let links = [
  'https://abc.pagerduty.com/incidentsgoogle',
  'https://abc.pagerduty.com/incidents/',
  'https://abc.facebook.com'
];

As seen already, this approach would fail for strings with substring present in the links array.

To avoid such issues, change the process function to:

const process = (links, mailBody) => {
  let prefix = 'http://test.io?redirect_uri='
  return mailBody.replace(/( href=["'])/g, "$1" + prefix);
};

Related