Большинство выражений здесь решают отдельные конкретные случаи использования.
Это нормально, но я предпочитаю подход "всегда работает".
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, я рекомендую использовать более параноидальный:
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) : '') + ')');
RegExp.escape
в настоящее время работаю, и любой, кто считает, что у них есть ценный вклад, может помочь. core-js и другие polyfills предлагают это.