Есть ли функция RegExp.escape в Javascript?
Я просто хочу создать регулярное выражение из любой возможной строки.
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
Есть ли встроенный метод для этого? Если нет, что люди используют? Ruby имеет RegExp.escape
. Я не чувствую, что мне нужно написать свое, там должно быть что-то стандартное. Спасибо!
Ответы
Ответ 1
Недопустимая функция, связанная выше. Он не может выйти из ^
или $
(начало и конец строки) или -
, которое в группе символов используется для диапазонов.
Используйте эту функцию:
RegExp.escape= function(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
Хотя на первый взгляд это может показаться излишним, экранирование -
(а также ^
) делает функцию, подходящую для экранирования символов, вставляться в класс символов, а также тело регулярного выражения.
Escaping /
делает функцию, подходящую для экранирующих символов, использоваться в литературе JS regex для последующего eval.
Поскольку нет недостатков, чтобы избежать любого из них, имеет смысл убежать, чтобы охватить более широкие варианты использования.
И да, это разочаровывает неудача, что это не часть стандартного JavaScript.
Ответ 2
Для тех, кто использует lodash, с версии v3.0.0, функция _. escapeRegExp встроена:
_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'
И если вам не нужна полная библиотека lodash, вам может потребоваться только эта функция!
Ответ 3
Большинство выражений здесь описывают отдельные конкретные варианты использования.
Это хорошо, но я предпочитаю подход "всегда работает".
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.
-
!
: Отменяет группу нулевой ширины.
-
<
/=
: Часть спецификаций группы нулевой ширины.
Примечания:
-
/
не является строго необходимым в любом вкусе регулярного выражения. Тем не менее, он защищает, если кто-то (дрожь) делает eval("/" + pattern + "/");
.
-
,
гарантирует, что если строка должна быть целым числом в числовом спецификаторе, она будет корректно вызывать ошибку компиляции RegExp вместо того, чтобы молча выполнять компиляцию.
-
#
и \s
не нужно бежать в JavaScript, но делать это во многих других вариантах. Они сбегают здесь, если регулярное выражение будет передано в другую программу.
Если вам также необходимо проверять будущее регулярное выражение от возможных дополнений к возможностям JavaScript-регекса JavaScript, я рекомендую использовать более параноидальный:
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) : '') + ')');
Ответ 4
Руководство по регулярным выражениям для сети разработчиков Mozilla предоставляет следующую функцию:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
Ответ 5
В виджетах jQueryUI autocomplete (версия 1.9.1) они используют немного другое регулярное выражение (строка 6753), здесь это регулярное выражение в сочетании с подходом @bobince.
RegExp.escape = function( value ) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
Ответ 6
Ничто не должно препятствовать простому экранированию каждого не-буквенно-цифрового символа:
usersString.replace(/(?=\W)/g, '\\');
Вы теряете определенную степень удобочитаемости при выполнении re.toString()
, но вы выигрываете большую простоту (и безопасность).
В соответствии с ECMA-262, с одной стороны, регулярные выражения "синтаксические символы" всегда не являются алфавитно-цифровыми, так что результат является безопасным, а специальные escape-последовательности (\d
, \w
, \n
) всегда являются буквенно-цифровыми, так что не будут выдаваться ложные контрольные экраны.
Ответ 7
Существует предложение ES7 для RegExp.escape в https://github.com/benjamingr/RexExp.escape/, а polyfill доступно https://github.com/ljharb/regexp.escape.
Ответ 8
Это более короткая версия.
RegExp.escape = function(s) {
return s.replace(/[$-\/?[-^{|}]/g, '\\$&');
}
Это включает неметаные символы %
, &
, '
и ,
, но спецификация JavaScript RegExp позволяет это.
Ответ 9
escapeRegExp = function(str) {
if (str == null) return '';
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
Ответ 10
XRegExp имеет функцию escape:
XRegExp.escape('Escaped? <.>');
// -> 'Escaped\?\ <\.>'
Подробнее: http://xregexp.com/api/#escape
Ответ 11
Вместо того, чтобы избегать символов, которые могут вызвать проблемы в вашем регулярном выражении (например, черный список), почему бы не использовать вместо этого белый список. Таким образом, каждый символ считается испорченным, если он не соответствует.
В этом примере предположим следующее выражение:
RegExp.escape('be || ! be');
Это белый список букв, цифр и пробелов:
RegExp.escape = function (string) {
return string.replace(/([^\w\d\s])/gi, '\\$1');
}
Возврат:
"be \|\| \! be"
Это может ускользнуть от символов, которые не должны быть экранированы, но это не мешает вашему выражению (возможно, незначительные штрафные санкции - но это того стоит для безопасности).
Ответ 12
Функции в других ответах являются излишними для экранирования всех регулярных выражений (они могут быть полезны для экранирования частей регулярных выражений, которые позже будут объединены в большие регулярные выражения).
Если вы избегаете всего регулярного выражения и выполняетесь с ним, цитируя метасимволы, которые являются автономными (.
, ?
, +
, *
, ^
, $
, |
, \
) или начать что-то ((
, [
, {
) - все, что вам нужно:
String.prototype.regexEscape = function regexEscape() {
return this.replace(/[.?+*^$|({[\\]/g, '\\$&');
};
И да, это разочаровывает, что JavaScript не имеет такой функции, как этот встроенный.
Ответ 13
I Googled для онлайн-инструмента, который сделает это, но на удивление не смог найти его. Мог бы обернуться, чтобы однажды сбить кого-то, чтобы заткнуть промежуток, но в то же время сделал простой скрипт JS из принятого ответа:
https://jsfiddle.net/xnd0bkne/
StackOverflow требует, чтобы код был опубликован для скрипта JS, так что вот оно:
var s = prompt("Enter text to be REGEX-ESCAPED: ");
prompt("REGEX-ESCAPED (please select and copy the text below): ",
s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'));
Ответ 14
Другой (гораздо более безопасный) подход состоит в том, чтобы экранировать все символы (а не только несколько специальных, которые мы знаем в настоящее время), используя escape-формат Unicode \u{code}
:
function escapeRegExp(text) {
return Array.from(text)
.map(char => '\\u{${char.charCodeAt(0).toString(16)}}')
.join('');
}
console.log(escapeRegExp('a.b')); // '\u{61}\u{2e}\u{62}'
Обратите внимание, что для работы этого метода необходимо указать флаг u
:
var expression = new RegExp(escapeRegExp(usersString), 'u');
Ответ 15
Только когда-либо было и будет 12 метасимволов, которые нужно экранировать
считаться буквальным.
Неважно, что делается с экранированной строкой, вставленной в сбалансированный
Оболочка регулярных выражений, с добавлением, не имеет значения.
Заменить строку, используя этот
var escaped_string = oldstring.replace( /[\\^$.|?*+()[{]/g, '\\$&' );