0

I've got a text saved in a longer string and want to replace some words of the text with a highlighted version or a markdown link to a glossary page where the words are described. The words that should be filtered are stored in a string array.

At the moment my code looks something like this:

const text = "Lorem ipsum xxx dolor sit amet."
const highlightedWords = ["xxx", "yyy"]

const newText = text.replace(new RegExp(highlightedWords.join("|"), "gi"), "[same-word-here]('/glossary#same-word-here)');

The part with same-word-here should be the same word that was replaced before, but I don't know how to get this one in this position.

If you need a better known example: It should look like a linked article in a wikipedia text

Thanks for your help.

2 Answers2

0

Wrap the the expression in a capture group (), and then use $1 to use the capture group's content. You should also use \b (word boundary) to prevent text replacement when it's in another work, for example "xxxzzz".

const text = "Lorem ipsum xxx dolor sit amet."
const highlightedWords = ["xxx", "yyy"]

const newText = text.replace(new RegExp(`\\b(${highlightedWords.join("|")})\\b`, "gi"), "[$1]('/glossary#same-word-here)'");

console.log(newText)
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • If the "words" to be highlighted have any chance of containing regex special characters (like parentheses or square brackets), [they can be escaped before joining them](https://stackoverflow.com/q/3561493/1426891). – Jeff Bowman Apr 19 '22 at 11:39
  • Thank you! This seems to works for me. Never really heard of this feature before. – nolliebigspin Apr 19 '22 at 12:13
0

If I understand your goal correctly, you don't need regex for this since you have an array of words to iterate through.

let text = 'Lorem ipsum xxx dolor sit yyy amet.';
const highlightedWords = ['xxx', 'yyy'];

for (word of highlightedWords) {
    if (text.includes(word))
        text = text.replace(word, `[${word}]('/glossary#${word})`);
}

console.log(newText);
// result: Lorem ipsum [xxx]('/glossary#xxx) dolor sit [yyy]('/glossary#yyy) amet.

Or use a new variable so you still have original if you need it

const text = 'Lorem ipsum xxx dolor sit yyy amet.';
const highlightedWords = ['xxx', 'yyy'];

let newText = text;
for (word of highlightedWords) {
    if (newText.includes(word))
        newText = newText.replace(word, `[${word}]('/glossary#${word})`);
}

console.log(newText);
// result: Lorem ipsum [xxx]('/glossary#xxx) dolor sit [yyy]('/glossary#yyy) amet.
isimmons
  • 2,016
  • 2
  • 20
  • 32
  • Thank you too! Both ways solved my problem. I mean in my case performance is not a thing because my function runs in next SSG, but would the for loop be more performant than a regular expression? Just asking for personal interest. – nolliebigspin Apr 20 '22 at 07:48
  • @nolliebigspin I have no idea. I learned about using join to make a regexp from an array thanks to your post and Ori Drori answer. I like it because it's a one liner. I just didn't understand it at first. Maybe someone more knowledgeable will comment on performance eventually. – isimmons Apr 20 '22 at 12:52