0

Let's say I have a string like so:

const sentence = "This is my custom string";

I want to highlight the words of a input field inside this sentence.

Let's say a say user typed a string and I have converted the separate words into an array like so:

["custom", "string", "is"]

I know want to replace the words in my sentence with a highlighted version of the words in my array. For a single word I would do something like this:

const word = 'custom';

const searchFor = new RegExp(`(${word})`, 'gi');
const replaceWith = '<strong class="highlight">$1</strong>';

const highlightedSentence = sentence.replace(searchFor, replaceWith);

How can I apply this logic with an array to the entire sentence?

I can't simply loop through it because the string will contain my highlighted class which will also be taken into the highlighting process the the second loop, third loop, etc.

This means that on a second loop if a user where to type:

"high custom"

I would highlight my highlighted class, leading to highlight inception.

For an example of what I mean try commenting/uncommenting the 2 highlighter functions:

https://jsfiddle.net/qh9ttvp2/1/

2 Answers 2

2

Your problem is that while replacing words, you replace already added html tag with .class 'highlight'.

Solution here could be to replace anything that is not html tag. Replace this line in you jsfiddle example.

const searchFor = new RegExp(`(${word})(?!([^<]+)?>)`, 'gi');
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, never knew this was possible to implement like this with regex. Time to dive a bit deeper into regex. Works like a charm.
1

You can split you sentence into array and check if your element is already highlighted:

let sentence = "This is a some type of long string with all kinds of words in it, all kinds.";
let sentenceArr = sentence.split(' '); // make an array 
const query = "kinds words all type";

function highlighter(query, sentence) {
  const words = query.match(/\S+/g);

  words.forEach((word) => {
      // Create a capture group since we are searching case insensitive.
      const searchFor = new RegExp(`(${word})`, 'gi');
      const replaceWith = '<strong class="highlight">$1</strong>';
      sentenceArr = sentenceArr.map(sw => (sw.indexOf('strong class="highlight"') === -1) ? sw.replace(searchFor, replaceWith) : sw); // if already highlited - skip
      //sentence = sentence.replace(searchFor, replaceWith);
  });
  
  // console.log(sentence);

  document.querySelector('.highlighted-sentence').innerHTML = sentenceArr.join(' '); // notice sentenceArr
}

// Works.
//highlighter('kinds words all type', sentence);

// Doesn't work.
highlighter('kinds words high', sentence);
<div class="highlighted-sentence"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.