bairavand
bairavand

Reputation: 357

Javascript RegExp for exact multiple words with special characters match

I'm using RegExp for multiple words match. It has dynamic values so when a special character like "(" comes it takes that as an expression and shows Uncaught SyntaxError: Invalid regular expression error.

let text = 'working text and (not working text'
let findTerm = ['working text', '(not working text']
let replaceFromRegExp = new RegExp('\\b'+`(${findTerm.join("|")})`+'\\b', 'g')
text = text.replace(replaceFromRegExp, match => "<mark>" + match + "</mark>")
console.log(text)

Upvotes: 1

Views: 1383

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626691

A \b word boundary matches any of the following three positions:

  1. Before the first character in the string, if the first character is a word character.
  2. After the last character in the string, if the last character is a word character.
  3. Between two characters in the string, where one is a word character and the other is not a word character. You need universal word boundaries that will require a non-word char or start of string before a search word, and a non-word char or end of string after a search string.

Note you need to also sort the findTerm items in the descending order by length to avoid overlapping term issues.

Finally, do not forget to escape the findTerm items to be used in a regex pattern.

You can use

let text = 'working text and (not working text'
let findTerm = ['working text', '(not working text']
findTerm.sort((a, b) => b.length - a.length);
let replaceFromRegExp = new RegExp(String.raw`(?!\B\w)(?:${findTerm.map(x => x.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')).join("|")})(?!\B\w)`, 'g')
console.log(replaceFromRegExp)
text = text.replace(replaceFromRegExp, "<mark>$&</mark>")
console.log(text)

Note that "<mark>$&</mark>" is a shorter way of saying match => "<mark>" + match + "</mark>", as $& is a backreference to the whole match value in a string replacement pattern.

The regex is

/(?!\B\w)(?:\(not working text|working text)(?!\B\w)/g

See the regex #1 demo. Details:

  • (?!\B\w) - either a non-word boundary if the next char is not a word char, or a word boundary if the next char is a word char
  • (?:\(not working text|working text) - a non-capturing group matching one of the alternative patterns set in the findTerm array
  • (?!\B\w) - either a non-word boundary if the next char is not a word char, or a word boundary if the next char is a word char

Upvotes: 1

Related Questions