可能的重复: Javascript中有RegExp.escape函数吗?

我试图建立一个基于用户输入的javascript正则表达式:

function FindString(input) {
    var reg = new RegExp('' + input + '');
    // [snip] perform search
}

但是当用户输入包含?或者*,因为它们被解释为正则表达式的特殊值。事实上,如果用户在他们的字符串中放入一个不平衡的(或[,正则表达式甚至是无效的。

什么是javascript函数正确转义所有特殊字符用于正则表达式?


当前回答

短甜(更新2021年)

要转义RegExp本身:

function escapeRegExp(string) {
    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

转义替换字符串:

function escapeReplacement(string) {
    return string.replace(/\$/g, '$$$$');
}

例子

所有转义的RegExp字符:

escapeRegExp("All of these should be escaped: \ ^ $ * + ? . ( ) | { } [ ]");
>>> "All of these should be escaped: \\ \^ \$ \* \+ \? \. \( \) \| \{ \} \[ \] "

查找并替换字符串:

var haystack = "I love $x!";

var needle = "$x";
var safeNeedle = escapeRegExp(needle); // "\\$x"

var replacement = "$100 bills"
var safeReplacement = escapeReplacement(replacement); // "$$100 bills"

haystack.replace(
  new RegExp(safeNeedle, 'g'),
  escapeReplacement(safeReplacement),
);
// "I love $100 bills!"

(注:以上不是原答案;它被编辑成来自MDN的视频。这意味着它不匹配你将在下面的npm代码中找到的内容,也不匹配下面的长答案中显示的内容。这些评论现在也令人困惑。我的建议是:使用上面的方法,或者从MDN上获取,忽略这个答案的其余部分。达伦,2019年11月)

安装

在npm中可用escape-string-regexp

npm install --save escape-string-regexp

Note

参见MDN: Javascript指南:正则表达式

其他符号(~`!@ #……)可以不受后果地逃脱,但不是必须如此。

.

.

.

.

测试用例:一个典型的url

escapeRegExp("/path/to/resource.html?search=query");

>>> "\/path\/to\/resource\.html\?search=query"

长回答

如果你打算使用上面的函数,至少在你的代码文档中链接到这个堆栈溢出的帖子,这样它看起来就不会像一个难以测试的疯狂巫术。

var escapeRegExp;

(function () {
  // Referring to the table here:
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/regexp
  // these characters should be escaped
  // \ ^ $ * + ? . ( ) | { } [ ]
  // These characters only have special meaning inside of brackets
  // they do not need to be escaped, but they MAY be escaped
  // without any adverse effects (to the best of my knowledge and casual testing)
  // : ! , = 
  // my test "~!@#$%^&*(){}[]`/=?+\|-_;:'\",<.>".match(/[\#]/g)

  var specials = [
        // order matters for these
          "-"
        , "["
        , "]"
        // order doesn't matter for any of these
        , "/"
        , "{"
        , "}"
        , "("
        , ")"
        , "*"
        , "+"
        , "?"
        , "."
        , "\\"
        , "^"
        , "$"
        , "|"
      ]

      // I choose to escape every character with '\'
      // even though only some strictly require it when inside of []
    , regex = RegExp('[' + specials.join('\\') + ']', 'g')
    ;

  escapeRegExp = function (str) {
    return str.replace(regex, "\\$&");
  };

  // test escapeRegExp("/path/to/res?search=this.that")
}());

其他回答

短甜(更新2021年)

要转义RegExp本身:

function escapeRegExp(string) {
    return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

转义替换字符串:

function escapeReplacement(string) {
    return string.replace(/\$/g, '$$$$');
}

例子

所有转义的RegExp字符:

escapeRegExp("All of these should be escaped: \ ^ $ * + ? . ( ) | { } [ ]");
>>> "All of these should be escaped: \\ \^ \$ \* \+ \? \. \( \) \| \{ \} \[ \] "

查找并替换字符串:

var haystack = "I love $x!";

var needle = "$x";
var safeNeedle = escapeRegExp(needle); // "\\$x"

var replacement = "$100 bills"
var safeReplacement = escapeReplacement(replacement); // "$$100 bills"

haystack.replace(
  new RegExp(safeNeedle, 'g'),
  escapeReplacement(safeReplacement),
);
// "I love $100 bills!"

(注:以上不是原答案;它被编辑成来自MDN的视频。这意味着它不匹配你将在下面的npm代码中找到的内容,也不匹配下面的长答案中显示的内容。这些评论现在也令人困惑。我的建议是:使用上面的方法,或者从MDN上获取,忽略这个答案的其余部分。达伦,2019年11月)

安装

在npm中可用escape-string-regexp

npm install --save escape-string-regexp

Note

参见MDN: Javascript指南:正则表达式

其他符号(~`!@ #……)可以不受后果地逃脱,但不是必须如此。

.

.

.

.

测试用例:一个典型的url

escapeRegExp("/path/to/resource.html?search=query");

>>> "\/path\/to\/resource\.html\?search=query"

长回答

如果你打算使用上面的函数,至少在你的代码文档中链接到这个堆栈溢出的帖子,这样它看起来就不会像一个难以测试的疯狂巫术。

var escapeRegExp;

(function () {
  // Referring to the table here:
  // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/regexp
  // these characters should be escaped
  // \ ^ $ * + ? . ( ) | { } [ ]
  // These characters only have special meaning inside of brackets
  // they do not need to be escaped, but they MAY be escaped
  // without any adverse effects (to the best of my knowledge and casual testing)
  // : ! , = 
  // my test "~!@#$%^&*(){}[]`/=?+\|-_;:'\",<.>".match(/[\#]/g)

  var specials = [
        // order matters for these
          "-"
        , "["
        , "]"
        // order doesn't matter for any of these
        , "/"
        , "{"
        , "}"
        , "("
        , ")"
        , "*"
        , "+"
        , "?"
        , "."
        , "\\"
        , "^"
        , "$"
        , "|"
      ]

      // I choose to escape every character with '\'
      // even though only some strictly require it when inside of []
    , regex = RegExp('[' + specials.join('\\') + ']', 'g')
    ;

  escapeRegExp = function (str) {
    return str.replace(regex, "\\$&");
  };

  // test escapeRegExp("/path/to/res?search=this.that")
}());