How to create a regular expression in typescript to bold trigrams from a search phrase

I am trying to create a regular expression in javascript / typescript to bold search phrases from an array, in this case from an array of trigrams.

An example array looks like this:

const trigrams = ['jon', 'ona', 'nat', 'ath', 'tha', 'han'];

const phrase = 'there is some text here with jonathan in it, and jon, and nat, and than';

My goal:

console.log(phrase);
// prints this:
there is some text here with <b>jonathan</b> in it, and <b>jon</b>, and <b>nat</b>, and <b>than</b>

I would like to bold everything in the phrase that is matched by each array element, but sometimes those letters overlap leaving <b> with in <b> tags.

Here is my code:

let v = phrase;
for (const trigram of trigrams) {

  // split trigram into letters
  const c = trigram.split('');

  // create regex
  const reg = `(<b>)?(\w*${c[0]}\w*)(<\/b>)?(<b>)?(\w*${c[1]}\w*)(<\/b>)?(<b>)?(\w*${c[2]}\w*)(<\/b>)?`;
  let re = new RegExp(reg, 'gi');

  // replace all previous bolds with just one bold
  v = v.replace(re, "<b>$1$3$7</b>");
}
console.log(v);

I can’t wrap my head around this for the moment.

8 thoughts on “How to create a regular expression in typescript to bold trigrams from a search phrase”

  1. Got it working. I had to get rid of the extra <b> tags that are created:

    let v = phrase;
    for (const trigram of args) {
    
      // split trigram into letters
      const c = trigram.split('');
    
      // create regex
      const reg = `(<\/?b>)*(${c[0]})(<\/?b>)*(${c[1]})(<\/?b>)*(${c[2]})(<\/?b>)*`;
      let re = new RegExp(reg, 'gi');
    
      // add bolded trigrams
      v = v.replace(re, "<b>$2$4$6</b>");
    }
    // get rid of extra <b>
    const r = new RegExp(/<b>(\w+)<b>/, 'i');
    while (v.match(r)) {
      v = v.replace(r, "<b>$1");
    }
    
    console.log(v);
    

    I imagine there is a simpler way of doing this. If anyone knows, please post here. Thanks!

    Reply

Leave a Comment