записи поиска, имеющие специальные символы в mongoDB [duplicate]

321
задан Lance Pollard 24 August 2010 в 23:22
поделиться

12 ответов

Недопустимая функция, связанная выше. Он не может избежать ^ или $ (начало и конец строки) или -, которые в группе символов используются для диапазонов.

Используйте эту функцию:

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

Хотя на первый взгляд может показаться ненужным, экранирование - (а также ^) делает функцию, подходящую для экранирования символов, вставляться в класс символов, а также тело регулярного выражения.

Escaping / делает функцию подходящей для экранирующих символов, которые будут использоваться в литеральном выражении JS для последующего eval.

Поскольку нет недостатка для экранирования любого из них, имеет смысл

И да, неутешительно, что это не является частью стандартного JavaScript.

410
ответ дан nhahtdh 23 August 2018 в 22:07
поделиться

XRegExp имеет функцию escape:

XRegExp.escape('Escaped? <.>'); // -> 'Escaped\?\ <\.>'

Подробнее: http://xregexp.com/api/#escape

0
ответ дан Antoine Dusséaux 23 August 2018 в 22:07
поделиться

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

В этом примере предположим следующее выражение:

RegExp.escape('be || ! be');

Это белый список букв, цифр и пробелов:

RegExp.escape = function (string) {
    return string.replace(/([^\w\d\s])/gi, '\\$1');
}

Возвраты:

"be \|\| \! be"

Это может привести к тому, что символы не должны быть экранированы, но это не мешает вашему выражению (может быть, некоторые незначительные штрафные санкции), но это того стоит ).

0
ответ дан bashaus 23 August 2018 в 22:07
поделиться

Ничто не должно мешать вам просто избегать каждого не буквенно-цифрового символа:

usersString.replace(/(?=\W)/g, '\\');

Вы теряете определенную степень удобочитаемости при выполнении re.toString(), но вы выигрываете большую простоту (и безопасность) .

Согласно ECMA-262, с одной стороны, регулярные выражения «синтаксические символы» всегда не являются алфавитно-цифровыми, так что результат является безопасным, а специальные escape-последовательности (\d, \w , \n) всегда являются буквенно-цифровыми, так что не будут выдаваться ложные контрольные экраны.

8
ответ дан daluege 23 August 2018 в 22:07
поделиться

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

Если вы избегаете всего регулярного выражения и выполняетесь с ним, цитируя метасимволы, которые являются автономными (., ?, +, *, ^, $, |, \) или начать что-то ((, [, {) - это все, что вам нужно:

String.prototype.regexEscape = function regexEscape() {
  return this.replace(/[.?+*^$|({[\\]/g, '\\$&');
};

И да, неутешительно, что JavaScript не имеет такой функции, как эта встроенная -в.

-1
ответ дан Dan Dascalescu 23 August 2018 в 22:07
поделиться

Большинство выражений здесь решают одно конкретные случаи использования.

Это нормально, но я предпочитаю подход «всегда работает».

function regExpEscape(literal_string) {
    return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}

Это «полностью исчезнет», буквальная строка для любого из следующих применений в регулярных выражениях:

  • Вставка в регулярном выражении. Например. new RegExp(regExpEscape(str))
  • Вставка в класс символов. Например. new RegExp('[' + regExpEscape(str) + ']')
  • Вставка в спецификаторе целых чисел. Например. new RegExp('x{1,' + regExpEscape(str) + '}')
  • Выполнение в двигателях с регулярными выражениями, отличными от JavaScript.

Описанные специальные символы:

  • -: создает диапазон символов в классе символов.
  • [ / ]: Запускает / завершает класс символов.
  • { / }: Запускает / завершает спецификатор нумерации .
  • ( / ): Запускает / завершает группу.
  • * / + / ?: Определяет тип повторения.
  • .: соответствует любому символу.
  • \: стирает символы и запускает объекты.
  • ^: указывает начало зоны соответствия и отменяет соответствие в символьный класс.
  • $: Задает конец зоны совпадения.
  • |: Определяет чередование.
  • #: указывает комментарий на свободном расстоянии
  • \s: Игнорируется в режиме свободного пробела.
  • ,: Разделяет значения в спецификаторе нумерации.
  • /: Запускает или завершает выражение.
  • :: Завершает специальные типы групп и часть классов символов в стиле Perl. [/ g 20]
  • !: Отклоняет группу нулевой ширины.
  • < / =: Часть спецификаций группы нулевой ширины.

Примечания :

  • / не является строго необходимым в любом вкусе регулярного выражения. Тем не менее, он защищает, если кто-то (содрогание) делает eval("/" + pattern + "/");.
  • , гарантирует, что если строка должна быть целым числом в числовом спецификаторе, она будет должным образом вызывают ошибку компиляции RegExp вместо того, чтобы молча выполнять компиляцию.
  • # и \s не нужно бежать в JavaScript, но делать это во многих других вариантах. Они ускользнуты здесь, если регулярное выражение будет передано в другую программу.

Если вам также необходимо будущее регулярное выражение против возможных дополнений к движку JavaScript regex возможности, я рекомендую использовать более параноид:

function regExpEscapeFuture(literal_string) {
    return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}

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


Для по-настоящему здравомыслящий, рассмотрим этот краевой случай:

var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');

Этот должен компилироваться в JavaScript, но не будет в некоторых других вариантах. Если намереваться передать другой вкус, нулевой случай s === '' должен быть независимо проверен, например:

var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
28
ответ дан Gras Double 23 August 2018 в 22:07
поделиться

Для тех, кто использует lodash, , так как v3.0.0 , функция _. escapeRegExp встроена:

_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'

И, в событие, которое вы не хотите требовать полной библиотеки lodash, вы можете потребовать только эту функцию !

63
ответ дан gustavohenke 23 August 2018 в 22:07
поделиться

Это более короткая версия.

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

Это включает неметаные символы из %, &, ' и ,, но спецификация JavaScript RegExp позволяет это.

4
ответ дан kzh 23 August 2018 в 22:07
поделиться

В виджетах автозаполнения jQueryUI (версия 1.9.1) они используют несколько другое регулярное выражение (строка 6753), вот регулярное выражение, объединенное с подходом @bobince.

RegExp.escape = function( value ) {
     return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
17
ответ дан Pierluc SS 23 August 2018 в 22:07
поделиться
escapeRegExp = function(str) {
  if (str == null) return '';
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
1
ответ дан pzaenger 23 August 2018 в 22:07
поделиться

Существует предложение ES7 для RegExp.escape в https://github.com/benjamingr/RexExp.escape/ , с полиполем, доступным в https://github.com /ljharb/regexp.escape.

7
ответ дан user 23 August 2018 в 22:07
поделиться

Руководство разработчика Mozilla Developer Network для регулярных выражений предоставляет эту функцию экранирования:

function escapeRegExp(string){
    return string.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
}
12
ответ дан user113215 23 August 2018 в 22:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: