Javascript Regex Word Boundary с необязательным несловным символом

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

['hello', '#hello', '@hello'];

Вот мой код, который включает в себя попытку, найденную в посте:

let userStr = 'why hello there, or should I say #hello there?';

let keyword = '#hello';

let re = new RegExp(`/(#\b${userStr})\b/`);

re.exec(keyword);
  • Это было бы здорово, если бы строка всегда начиналась с #, но это не так.
  • Я тогда попробовал это /(#?\b${userStr})\b/, но если строка начинается с #, он пытается соответствовать ##hello,
  • matchThis str может быть любым из 3-х примеров в массиве, а userStr может содержать несколько вариантов matchThis но только один будет точным

2 ответа

Решение

Вам нужно учесть 3 вещи здесь:

  • Главное, что \b граница слова является контекстно-зависимой конструкцией, и если ваш ввод не всегда буквенно-цифровой, вам нужны однозначные границы слова
  • Вам нужно удвоить специальные символы в escape-символе конструктора RegExp
  • Когда вы передаете переменную в регулярное выражение, вы должны убедиться, что все специальные символы правильно экранированы.

использование

let userStr = 'why hello there, or should I say #hello there?';
let keyword = '#hello';
let re_pattern = `(?:^|\\W)(${keyword.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')})(?!\\w)`;
let res = [], m;

// To find a single (first) match
console.log((m=new RegExp(re_pattern).exec(userStr)) ? m[1] : "");

// To find multiple matches:
let rx = new RegExp(re_pattern, "g");
while (m=rx.exec(userStr)) {
    res.push(m[1]);
}
console.log(res);

Описание шаблона

  • (?:^|\\W) - не захватывающая строка, совпадающая с началом строки или любой не состоящий из слов символ
  • (${keyword.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}) - Группа 1: значение ключевого слова с экранированными специальными символами
  • (?!\\w) - негативный взгляд, который не соответствует совпадению, если сразу после текущего местоположения есть слово char.

Проверьте, начинается ли ключевое слово со специального символа. Если это так, не включайте его в регулярное выражение.

var re;
if ("#@".indexOf(keyword[0]) == -1) {
    re = new RegExp(`[@#]?\b${keyword}\b`);
} else {
    re = new RegExp(`\b${keyword}\b`);
}
Другие вопросы по тегам