I have a JSX element that displays a search result and the result has the matching search term highlighted wherever it appears in the result. For instance if searchTerm = 'hello world'
and result.text = 'foo bar hello world it is hello'
, it will be highlighted like so: 'foo bar hello world it is hello'. This solution only works for perfect matches however.
// JSX that displays a search result with matches highlighted
<div style={{ whiteSpace: 'normal' }}>
{highlightMatch(documentationIndexState.searchTerm, result.text)}
</div>
// highlight function
function highlightMatch(searchTerm: string, text: string) {
const parts = text.split(new RegExp(`(${searchTerm})`, 'gi'));
return (
<span>
{' '}
{parts.map((part, i) => (
<span
key={i}
style={
part.toLowerCase() === searchTerm.toLowerCase() ? { fontWeight: 'bold', color: 'yellow' } : {}
}
>
{part}
</span>
))}{' '}
</span>
);
}
How could I modify the regex to have any matching word be highlighted in the text? So the searchTerm would have to be split up into individual words and the resulting highlights would be 'foo bar hello world it is hello'.
CodePudding user response:
Here is a modified highlightMatch()
function using plan JavaScript so that it can be shown here in the JS snippet -- you can convert that back into TypeScript:
function highlightMatch(searchTerm, text) {
const escapedTerm = searchTerm.replace(/[.* ?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp('\\b' escapedTerm '\\b', 'gi');
return text.replace(regex, m => '<span >' m '</span>');
}
const text = 'foo bar hello world it is hello';
const searchTerm = 'hello world';
let result = highlightMatch(searchTerm, text);
console.log(result);
document.getElementById('result').innerHTML = result;
.highlightText {
font-weight: bold;
background-color: yellow;
}
<div id="result"></div>
Notes:
- the search term needs to be escaped, so that chars special to regex can be searched literally:
/[.* ?^${}()|[\]\\]/g
- the search regex is created dynamically with the escaped search term
- the search term uses
\b
word boundaries to avoid false hits, such as texthighlighted
with textlight
(remove the word boundaries if you want to highlight text within words) - the
.replace()
encloses the matched text in a span with classhighlightText
CodePudding user response:
I am new to react, but maybe this will help: (hello)|(world)
.
Add it to this line: new RegExp('(hello)|(world)')