Как правильно выполнять символы в регулярном выражении

Я хочу выполнить строковый поиск внутри строки. Просто говоря MySTR.search(Needle).

Проблема возникает, когда эта строка needle содержит специальные регулярные выражения, такие как *, + и т.д. Ошибка с ошибкой invalid quantifier.

Я просмотрел веб-сайт и узнал, что строка может быть экранирована с помощью \Q some string \E.

Однако это не всегда приводит к желаемому поведению. Например:

var sNeedle = '*Stars!*';
var sMySTR = 'The contents of this string have no importance';
sMySTR.search('\Q' + sNeedle + '\E');

Результат равен -1. OK.

var sNeedle = '**Stars!**';
var sMySTR = 'The contents of this string have no importance';
sMySTR.search('\Q' + sNeedle + '\E');

Результат - "недопустимый квантификатор". Это происходит потому, что два или более специальных символа "касаются друг друга", потому что:

var sNeedle = '*Dont touch me*Stars!*Dont touch me*';
var sMySTR = 'The contents of this string have no importance';
sMySTR.search('\Q' + sNeedle + '\E');

Будет работать нормально.

Я знаю, что могу сделать функцию escapeAllBadChars(sInStr) и просто добавлять двойные слэши перед каждым возможным специальным символом регулярного выражения, но мне интересно, есть ли более простой способ сделать это?

Ответы

Ответ 1

\Q...\E не работает в JavaScript (по крайней мере, они ничего не избегают...), как вы можете видеть:

var s = "*";
print(s.search(/\Q*\E/));
print(s.search(/\*/));

дает:

-1
0

как вы можете видеть на Ideone.

Следующие символы должны быть экранированы:

  • (
  • )
  • [
  • {
  • *
  • +
  • .
  • $
  • ^
  • \
  • |
  • ?

Итак, что-то вроде этого:

function quote(regex) {
  return regex.replace(/([()[{*+.$^\\|?])/g, '\\$1');
}

Нет, ] и } не нужно бежать: они не имеют особого значения, только их открывающие счетные части.

Обратите внимание, что при использовании литерального регулярного выражения /.../ вам также необходимо избежать / char. Однако / не является метасимволом регулярного выражения: при использовании его в объекте RegExp ему не требуется escape.

Ответ 2

Я просто окунаю ноги в Javascript, но есть ли причина, по которой вам нужно использовать механизм регулярных выражений? Как насчет

var sNeedle = '*Stars!*';
var sMySTR = 'The contents of this string have no importance';
if ( sMySTR.indexOf(sNeedle) > -1 ) {
   //found it
}

Ответ 3

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

RegExp.escape = function(text) {
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}

В качестве альтернативы вы можете попробовать и использовать отдельную библиотеку, такую ​​как XRegExp, которая уже обрабатывает нюансы, которые вы пытаетесь повторно решить.

Ответ 4

Дубликат fooobar.com/info/1809/...

Это соответствует MDN (см. объяснение в вышеприведенной статье):

function escapeRegExp(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}