Я просто хочу создать регулярное выражение из любой возможной строки.
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
Есть ли встроенный метод для этого? Если нет, что люди используют? Руби имеет RegExp.escape
. Я не чувствую, что мне нужно писать свое, должно быть что-то стандартное. Спасибо!
javascript
regex
Лэнс Поллард
источник
источник
RegExp.escape
в настоящее время работаю, и любой, кто считает, что у них есть ценный вклад, может помочь. core-js и другие polyfills предлагают это.Ответы:
Связанная выше функция недостаточна. Не удается избежать
^
или$
(начало и конец строки), или-
, который в группе символов используется для диапазонов.Используйте эту функцию:
Хотя это может показаться на первый взгляд ненужным, экранирование
-
(так же как и^
) делает функцию подходящей для экранирования символов, которые будут вставлены в класс символов, а также в тело регулярного выражения.Экранирование
/
делает функцию подходящей для экранирования символов, которые будут использоваться в литерале регулярного выражения JS для последующего вычисления.Так как нет побочных эффектов от побега любого из них, имеет смысл сбежать, чтобы охватить более широкие варианты использования.
И да, досадно, что это не является частью стандартного JavaScript.
источник
/
на всехquotemeta
(\Q
), Pythonre.escape
, PHPpreg_quote
, RubyRegexp.quote
...var e = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g;
и тогда ваша функция будетreturn s.replace(e, '\\$&');
такой. Таким образом, вы создаете экземпляр RegExp только один раз.RegExp.escape
реализована версия , реализация которой отличается от вашей? Не лучше ли, чтобы эта функция ни к чему не была привязана?Для тех , кто с помощью lodash, поскольку v3.0.0 _.escapeRegExp функция встроена в:
И, если вам не нужна полная библиотека lodash, вам может потребоваться только эта функция !
источник
escapeRegExp
функция.Большинство выражений здесь решают отдельные конкретные случаи использования.
Это нормально, но я предпочитаю подход "всегда работает".
Это «полностью экранирует» литеральную строку для любого из следующих применений в регулярных выражениях:
new RegExp(regExpEscape(str))
new RegExp('[' + regExpEscape(str) + ']')
new RegExp('x{1,' + regExpEscape(str) + '}')
Охваченные специальные символы:
-
: Создает диапазон символов в классе символов.[
/]
: Запускает / заканчивает класс персонажа.{
/}
: Запускает / заканчивает спецификатор нумерации.(
/)
: Запускает / заканчивает группу.*
/+
/?
: Определяет тип повторения..
: Соответствует любому персонажу.\
: Экранирует персонажей и запускает сущности.^
: Определяет начало зоны сопоставления и отменяет сопоставление в классе символов.$
: Указывает конец соответствующей зоны.|
: Определяет чередование.#
: Указывает комментарий в режиме свободного пробела.\s
: Игнорируется в режиме свободного пространства.,
: Разделяет значения в спецификаторе нумерации./
: Начинается или заканчивается выражение.:
: Завершает специальные типы групп и часть классов символов в стиле Perl.!
: Отрицает группу нулевой ширины.<
/=
: Часть спецификации группы нулевой ширины.Ноты:
/
не является строго необходимым в любом аромате регулярного выражения. Тем не менее, это защищает в случае, если кто-то (дрожь) делаетeval("/" + pattern + "/");
.,
гарантирует, что если строка должна быть целым числом в числовом спецификаторе, она будет правильно вызывать ошибку компиляции RegExp вместо того, чтобы молча компилировать неправильно.#
и\s
не нужно экранировать в JavaScript, но делают во многих других вариантах. Они здесь экранированы на случай, если регулярное выражение будет позже передано другой программе.Если вам также необходимо защитить регулярное выражение от потенциальных добавлений к возможностям механизма регулярных выражений JavaScript, я рекомендую использовать более параноидальный:
Эта функция экранирует все символы, кроме тех, которые явно гарантированно не будут использоваться для синтаксиса в будущих вариантах регулярных выражений.
Для истинных любителей санитарии рассмотрим этот крайний случай:
Это должно хорошо скомпилироваться в JavaScript, но не будет в некоторых других вариантах. Если вы намерены перейти к другому варианту, нулевой регистр
s === ''
должен быть проверен независимо, например, так:источник
/
Не нужно экранировать в[...]
классе символов.Руководство по регулярным выражениям в Mozilla Developer Network предоставляет следующую функцию:
источник
=
больше не включена.В виджете автозаполнения jQueryUI (версия 1.9.1) они используют немного другое регулярное выражение (строка 6753), вот регулярное выражение в сочетании с подходом @bobince.
источник
,
(что не является метасимволом), а также#
и пробелами, которые имеют значение только в режиме свободного пробела (который не поддерживается JavaScript). Тем не менее, они понимают это правильно, чтобы не избежать косой черты.$.ui.autocomplete.escapeRegex(myString)
.Ничто не должно мешать вам просто экранировать все не алфавитно-цифровые символы:
Вы теряете определенную степень читабельности при выполнении,
re.toString()
но вы получаете большую простоту (и безопасность).Согласно ECMA-262, с одной стороны, регулярное выражение «синтаксических символов» всегда не алфавитно-цифровой, так что результат является безопасным, и специальные управляющие последовательности (
\d
,\w
,\n
) всегда алфавитно - цифровой , такие , что никакие ложные ускользает управления не будет производиться ,источник
.replace(/[^\w]/g, '\\$&')
будет работать так же.new RegExp('🍎'.replace(/(?=\W)/g, '\\'), 'u')
выдает исключение, потому что\W
сопоставляет каждую единицу кода суррогатной пары отдельно, что приводит к недопустимым управляющим кодам..replace(/\W/g, "\\$&");
Существует предложение ES7 для RegExp.escape по адресу https://github.com/benjamingr/RexExp.escape/ , а полифилл доступен по адресу https://github.com/ljharb/regexp.escape .
источник
Это более короткая версия.
Это включает в себя не-мета - символы
%
,&
,'
, и,
, но спецификация JavaScript RegExp позволяет.источник
.
пропущено. И()
. Или нет?[-^
странно. Я не помню, что там.XRegExp имеет функцию escape:
XRegExp.escape('Escaped? <.>'); // -> 'Escaped\?\ <\.>'
Больше на: http://xregexp.com/api/#escape
источник
Вместо того, чтобы экранировать только символы, которые вызовут проблемы в вашем регулярном выражении (например, черный список), почему бы не использовать вместо этого белый список. Таким образом, каждый персонаж считается испорченным, если он не совпадает.
Для этого примера предположим следующее выражение:
Это белый список букв, цифр и пробелов:
Возвращает:
Это может скрывать символы, от которых не нужно убегать, но это не мешает вашему выражению (возможно, некоторые незначительные штрафы за время - но это стоит того для безопасности).
источник
источник
Функции в других ответах излишни для экранирования целых регулярных выражений (они могут быть полезны для экранирования частей регулярных выражений, которые впоследствии будут объединены в большие регулярные выражения).
Если вы бежите все регулярное выражение и сделали с ним, ссылаясь на метасимволы , которые являются либо автономными (
.
,?
,+
,*
,^
,$
,|
,\
) или начать что - то ((
,[
,{
) есть все , что вам нужно:И да, разочаровывает то, что в JavaScript нет такой функции, как эта.
источник
(text)next
и вставляете его в:(?:
+ input +)
. Ваш метод выдаст результирующую строку,(?:\(text)next)
которая не компилируется. Обратите внимание, что это вполне разумная вставка, а не какая-то сумасшедшая, такая какre\
+ input +re
(в этом случае программиста можно обвинить в том, что он сделал что-то глупое)\
следует избегать, так как ваше регулярное выражение останется\w
нетронутым. Кроме того, JavaScript, похоже, не допускает трейлинг)
, по крайней мере, именно для этого Firefox выдает ошибку.)
Другой (гораздо более безопасный) подход состоит в том, чтобы экранировать все символы (а не только несколько специальных, которые мы знаем в настоящее время), используя escape-формат Unicode
\u{code}
:Обратите внимание, что вам нужно передать
u
флаг, чтобы этот метод работал:источник
Только когда-либо было и будет 12 метасимволов, которые нужно экранировать,
чтобы считаться литералом.
Неважно, что делается с экранированной строкой, вставленной в сбалансированную
оболочку регулярных выражений, с добавлением, не имеет значения.
Заменить строку, используя это
источник
]
?