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].
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.