#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
Граница слова соответствует любой из следующих трех позиций:
- Перед первым символом в строке, если первый символ является символом слова.
- После последнего символа в строке, если последний символ является символом слова.
- Между двумя символами в строке, где один является символом слова, а другой не является символом слова. Вам нужны универсальные границы слов, для которых потребуется символ без слов или начало строки перед поисковым словом, а также символ без слов или конец строки после строки поиска.
Примечание.Вам также необходимо отсортировать 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. Спасибо за ответ. Я присоединился