Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to highlight a certain text on the contenteditable div?

The goal is to highlight certain words on the contenteditable div. Currently my approach is that using the regex to match the keywords that are inside { words } or [ words ].

const regexpSquareBracket = /\[[^\]]*\]/gm;
const regexCurlyBracket = /\{[^\}]*\}/gm;
  
const squareBracketMatches = text.match(regexpSquareBracket);
const curlyBracketMatches = text.match(regexCurlyBracket);

Above code working fine that correctly identifies this text.

Here is [the] sample [text] that matches the [certain words] in the given [text] and {highlight} the words in the text.

However the code I have for highlighting the text is not great because it only matches the single keyword rather than [multiple keywords compine].

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I need you to give me the solution for how to improve below code that also matches the multiple keywords compine.

var text = `Here is [the] sample [text] that matches the [certain words] in the given [text] and {highlight} the {words in the text}.`

// Find character index in a given list
const indexesOf = (arr, item) => 
  arr.reduce(
(acc, v, i) => (v === item && acc.push(i), acc),
  []);

const regexpSquareBracket = /\[[^\]]*\]/gm;
const regexCurlyBracket = /\{[^\}]*\}/gm;
  
const squareBracketMatches = text.match(regexpSquareBracket);
const curlyBracketMatches = text.match(regexCurlyBracket);

let splittedText = text.split(" ");

if (squareBracketMatches) {
  squareBracketMatches.forEach(function(match) {
var positions = indexesOf(splittedText, match)
positions.forEach(function(pos) {
  splittedText[pos] = `<span class="highlight-bracket">${splittedText[pos]}</span>`
})
  })
}

if (curlyBracketMatches) {
  curlyBracketMatches.forEach(function(match) {
var positions = indexesOf(splittedText, match)
positions.forEach(function(pos) {
  splittedText[pos] = `<span class="highlight-curly">${splittedText[pos]}</span>`
})
  })
}
console.log(splittedText.join(" "))

>Solution :

var text = `Here is [the] sample [text] that matches the [certain words] in the given [text] and {highlight} the {words in the text}.`

const removeDuplicates = arr => [...new Set(arr)];

const regexpSquareBracket = /\[[^\]]*\]/gm;
const regexCurlyBracket = /\{[^\}]*\}/gm;

const squareBracketMatches = text.match(regexpSquareBracket);
const curlyBracketMatches = text.match(regexCurlyBracket);

for (const sq of removeDuplicates(squareBracketMatches)) 
  text = text.replaceAll(sq, `<span class="highlight-bracket">${sq}</span>`)

for (const curly of removeDuplicates(curlyBracketMatches))
  text = text.replaceAll(curly, `<span class="highlight-curly">${curly}</span>`)

console.log(text)

If the any of the brackets can be nested, sort the matches by longer string first.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading