diff --git a/src/index.test.ts b/src/index.test.ts
index 6afcf53..5dfa6b6 100644
--- a/src/index.test.ts
+++ b/src/index.test.ts
@@ -131,3 +131,15 @@ describe('trim method', () => {
assert.strictEqual(highlighter.highlight(text, 'the').trim(5, false), 'The q')
})
})
+
+describe('special characters', () => {
+ it('should correctly highlight a text with special characters', () => {
+ const text = 'C++ is a hell of a language'
+ const searchTerm = 'C++'
+ const expectedResult = 'C++ is a hell of a language'
+
+ const highlighter = new Highlight()
+
+ assert.strictEqual(highlighter.highlight(text, searchTerm).HTML, expectedResult)
+ })
+})
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index cf1eb1d..eda5413 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -36,7 +36,7 @@ export class Highlight {
const CSSClass = this.options.CSSClass ?? defaultOptions.CSSClass
const regexFlags = caseSensitive ? 'g' : 'gi'
const boundary = wholeWords ? '\\b' : ''
- const searchTerms = (caseSensitive ? searchTerm : searchTerm.toLowerCase()).trim().split(/\s+/).join('|')
+ const searchTerms = this.escapeRegExp(caseSensitive ? searchTerm : searchTerm.toLowerCase()).trim().split(/\s+/).join('|')
const regex = new RegExp(`${boundary}${searchTerms}${boundary}`, regexFlags)
const positions: Array<{ start: number, end: number }> = []
const highlightedParts: string[] = []
@@ -91,4 +91,8 @@ export class Highlight {
get HTML (): string {
return this._HTML
}
+
+ private escapeRegExp(string: string): string {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ }
}