Регулярное выражение Javascript для точного совпадения нескольких слов со специальными символами

#javascript #regex

Вопрос:

Я использую регулярное выражение для сопоставления нескольких слов. Он имеет динамические значения, поэтому, когда появляется специальный символ, такой как » ( » , он принимает это как выражение и показывает неперехваченную синтаксическую ошибку: Недопустимую ошибку регулярного выражения.

 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) 

Комментарии:

1. Ваш текст содержит специальный символ регулярного ( выражения . Если вы хотите, чтобы все тексты были буквальными, попробуйте сначала избежать их .

Ответ №1:

b Граница слова соответствует любой из следующих трех позиций:

  1. Перед первым символом в строке, если первый символ является символом слова.
  2. После последнего символа в строке, если последний символ является символом слова.
  3. Между двумя символами в строке, где один является символом слова, а другой не является символом слова. Вам нужны универсальные границы слов, для которых потребуется символ без слов или начало строки перед поисковым словом, а также символ без слов или конец строки после строки поиска.

Примечание.Вам также необходимо отсортировать findTerm элементы в порядке убывания по длине, чтобы избежать перекрывающихся проблем с терминами.

Наконец, не забудьте избежать findTerm элементов, которые будут использоваться в шаблоне регулярных выражений.

Вы можете использовать

 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)|b(?=w))(?:${findTerm.map(x => x.replace(/[-/\^$* ?.()|[]{}]/g, '\$amp;')).join("|")})(?:(?<=w)b|(?<!w)B)`, 'g')
// If the boundaries for special chars should not be checked remove B:
// let replaceFromRegExp = new RegExp(String.raw`(?:(?!w)|b(?=w))(?:${findTerm.map(x => x.replace(/[-/\^$* ?.()|[]{}]/g, '\$amp;')).join("|")})(?:(?<=w)b|(?<!w))`, 'g')
console.log(replaceFromRegExp)
text = text.replace(replaceFromRegExp, "<mark>$amp;</mark>")
console.log(text) 

Обратите внимание , что "<mark>$amp;</mark>" это более короткий способ сказать match => "<mark>" match "</mark>" , как $amp; и обратная ссылка на все значение соответствия в шаблоне замены строк.

Регулярное выражение является

 /(?:B(?!w)|b(?=w))(?:(not working text|working text)(?:(?<=w)b|(?<!w)B)/g
 

Или

 /(?:(?!w)|b(?=w))(?:(not working text|working text)(?:(?<=w)b|(?<!w))/g
 

Смотрите демонстрацию регулярного выражения № 1 и демонстрацию регулярного выражения № 2. Подробные сведения:

  • (?:B(?!w)|b(?=w)) — либо граница без слов, если следующий символ не является символом слова, либо граница слова, если следующий символ является символом слова
  • (?:(?!w)|b(?=w)) — либо следующий символ должен быть не словесным символом, либо непосредственно слева от текущего местоположения не должно быть словесного символа, а следующий должен быть словесным символом (если термин начинается со специального символа, граница не требуется).
  • (?:(not working text|working text) — группа без захвата, соответствующая одному из альтернативных шаблонов, установленных в findTerm массиве
  • (?:(?<=w)b|(?<!w)B) — либо граница слова, если предыдущий символ является символом слова, либо граница без слов, если предыдущий символ не является символом слова
  • (?:(?<=w)b|(?<!w)) — если предыдущий символ является символом слова, следующий не должен быть символом слова, или предыдущий символ не должен быть символом слова (если термин заканчивается специальным символом, граница не требуется)

Комментарии:

1. Это работает. Если нам не нужно точное совпадение всего слова, просто удалите b в этом регулярном выражении.

2. @Pyr На самом деле, если вам не нужно точное совпадение, удалите (?:B(?!w)|b(?=w)) и (?:(?<=w)b|(?<!w)B) .

3. Спасибо за ответ. Я присоединился