Javascript 中有 RegExp.escape 函数吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3561493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:11:59  来源:igfitidea点击:

Is there a RegExp.escape function in Javascript?

javascriptregex

提问by Lance Pollard

I just want to create a regular expression out of any possible string.

我只想从任何可能的字符串中创建一个正则表达式。

var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);

Is there a built in method for that? If not, what do people use? Ruby has RegExp.escape. I don't feel like I'd need to write my own, there's gotta be something standard out there. Thanks!

有没有内置的方法?如果不是,人们用什么?红宝石有RegExp.escape。我不觉得我需要自己写,那里必须有一些标准的东西。谢谢!

回答by bobince

The function linked above is insufficient. It fails to escape ^or $(start and end of string), or -, which in a character group is used for ranges.

上面链接的功能是不够的。它无法转义^or $(字符串的开头和结尾)或-,它在字符组中用于范围。

Use this function:

使用这个功能:

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

While it may seem unnecessary at first glance, escaping -(as well as ^) makes the function suitable for escaping characters to be inserted into a character class as well as the body of the regex.

虽然乍一看似乎没有必要,但转义-(以及^)使该函数适用于转义要插入字符类以及正则表达式主体的字符。

Escaping /makes the function suitable for escaping characters to be used in a JS regex literal for later eval.

转义/使该函数适用于转义要在 JS 正则表达式文字中使用的字符,以便稍后进行 eval。

As there is no downside to escaping either of them it makes sense to escape to cover wider use cases.

由于逃避它们中的任何一个都没有缺点,因此逃避以涵盖更广泛的用例是有意义的。

And yes, it is a disappointing failing that this is not part of standard JavaScript.

是的,这是一个令人失望的失败,这不是标准 JavaScript 的一部分。

回答by gustavohenke

For anyone using lodash, since v3.0.0a _.escapeRegExpfunction is built-in:

对于任何使用 lodash 的人,从 v3.0.0开始,内置了一个_.escapeRegExp函数:

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

And, in the event that you don't want to require the full lodash library, you may require just that function!

而且,如果您不想需要完整的 lodash 库,您可能需要该功能

回答by Pi Marillion

Most of the expressions here solve single specific use cases.

这里的大多数表达式都解决了单个特定用例。

That's okay, but I prefer an "always works" approach.

没关系,但我更喜欢“始终有效”的方法。

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

This will "fully escape" a literal string for any of the following uses in regular expressions:

这将“完全转义”正则表达式中以下任何用途的文字字符串:

  • Insertion in a regular expression. E.g. new RegExp(regExpEscape(str))
  • Insertion in a character class. E.g. new RegExp('[' + regExpEscape(str) + ']')
  • Insertion in integer count specifier. E.g. new RegExp('x{1,' + regExpEscape(str) + '}')
  • Execution in non-JavaScript regular expression engines.
  • 在正则表达式中插入。例如new RegExp(regExpEscape(str))
  • 插入字符类。例如new RegExp('[' + regExpEscape(str) + ']')
  • 插入整数计数说明符。例如new RegExp('x{1,' + regExpEscape(str) + '}')
  • 在非 JavaScript 正则表达式引擎中执行。

Special Characters Covered:

涵盖的特殊字符:

  • -: Creates a character range in a character class.
  • [/ ]: Starts / ends a character class.
  • {/ }: Starts / ends a numeration specifier.
  • (/ ): Starts / ends a group.
  • */ +/ ?: Specifies repetition type.
  • .: Matches any character.
  • \: Escapes characters, and starts entities.
  • ^: Specifies start of matching zone, and negates matching in a character class.
  • $: Specifies end of matching zone.
  • |: Specifies alternation.
  • #: Specifies comment in free spacing mode.
  • \s: Ignored in free spacing mode.
  • ,: Separates values in numeration specifier.
  • /: Starts or ends expression.
  • :: Completes special group types, and part of Perl-style character classes.
  • !: Negates zero-width group.
  • </ =: Part of zero-width group specifications.
  • -: 在字符类中创建字符范围。
  • [/ ]:开始/结束一个字符类。
  • {/ }:开始/结束一个数字说明符。
  • (/ ):开始/结束一个组。
  • */ +/ ?:指定重复类型。
  • .: 匹配任何字符。
  • \: 转义字符,并启动实体。
  • ^: 指定匹配区域的开始,并否定字符类中的匹配。
  • $: 指定匹配区域的结束。
  • |: 指定交替。
  • #: 在自由间距模式下指定注释。
  • \s: 在自由间距模式下被忽略。
  • ,: 分隔数值说明符中的值。
  • /: 开始或结束表达式。
  • :: 完成特殊的组类型,以及部分 Perl 风格的字符类。
  • !:否定零宽度组。
  • </ =:零宽度组规范的一部分。

Notes:

笔记:

  • /is not strictly necessary in any flavor of regular expression. However, it protects in case someone (shudder)does eval("/" + pattern + "/");.
  • ,ensures that if the string is meant to be an integer in the numerical specifier, it will properly cause a RegExp compiling error instead of silently compiling wrong.
  • #, and \sdo not need to be escaped in JavaScript, but do in many other flavors. They are escaped here in case the regular expression will later be passed to another program.
  • /在任何风格的正则表达式中都不是绝对必要的。但是,如果有人(不寒而栗)这样做,它会提供保护eval("/" + pattern + "/");
  • ,确保如果字符串是数字说明符中的整数,它将正确地导致 RegExp 编译错误,而不是静默编译错误。
  • #, 并且\s不需要在 JavaScript 中转义,但可以在许多其他风格中进行。它们在此处被转义,以防正则表达式稍后被传递给另一个程序。


If you also need to future-proof the regular expression against potential additions to the JavaScript regex engine capabilities, I recommend using the more paranoid:

如果您还需要针对 JavaScript 正则表达式引擎功能的潜在添加来验证正则表达式的未来,我建议使用更偏执的:

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

This function escapes every character except those explicitly guaranteed not be used for syntax in future regular expression flavors.

此函数会转义每个字符,但明确保证不会用于未来正则表达式风格中的语法的字符。



For the truly sanitation-keen, consider this edge case:

对于真正热衷于卫生的人,请考虑以下极端情况:

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

This shouldcompile fine in JavaScript, but will not in some other flavors. If intending to pass to another flavor, the null case of s === ''should be independently checked, like so:

这在 JavaScript 中应该可以很好地编译,但在其他一些风格中则不能。如果打算传递给另一种风格,s === ''则应独立检查的空情况,如下所示:

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

回答by quietmint

Mozilla Developer Network's Guide to Regular Expressionsprovides this escaping function:

Mozilla 开发者网络的正则表达式指南提供了这个转义函数:

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

回答by Pierluc SS

In jQueryUI's autocomplete widget (version 1.9.1) they use a slightly different regex (Line 6753), here's the regular expression combined with @bobince approach.

在 jQueryUI 的自动完成小部件(版本 1.9.1)中,它们使用了稍微不同的正则表达式(第 6753 行),这里是与 @bobince 方法相结合的正则表达式。

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

回答by filip

Nothing should prevent you from just escaping every non-alphanumeric character:

没有什么可以阻止您转义每个非字母数字字符:

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

You lose a certain degree of readability when doing re.toString()but you win a great deal of simplicity (and security).

这样做时你会失去一定程度的可读性,re.toString()但你赢得了大量的简单性(和安全性)。

According to ECMA-262, on the one hand, regular expression "syntax characters" are always non-alphanumeric, such that the result is secure, and special escape sequences (\d, \w, \n) are always alphanumeric such that no false control escapes will be produced.

根据 ECMA-262,一方面,正则表达式“语法字符”始终是非字母数字,因此结果是安全的,并且特殊转义序列 ( \d, \w, \n) 始终是字母数字,因此不会产生错误的控制转义.

回答by filip

There is an ES7 proposal for RegExp.escape at https://github.com/benjamingr/RexExp.escape/, with a polyfill available at https://github.com/ljharb/regexp.escape.

有一个ES7提案RegExp.escape在https://github.com/benjamingr/RexExp.escape/,与可用填充工具https://github.com/ljharb/regexp.escape

回答by kzh

This is a shorter version.

这是一个较短的版本。

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

This includes the non-meta characters of %, &, ', and ,, but the JavaScript RegExp specification allows this.

这包括非元字符%&',和,,但JavaScript的正则表达式规范允许这样做。

回答by Ravi Gadhia

escapeRegExp = function(str) {
  if (str == null) return '';
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\])/g, '\');
};

回答by Antoine Dusséaux

XRegExp has an escape function:

XRegExp 有一个转义函数:

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

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

More on: http://xregexp.com/api/#escape

更多信息:http: //xregexp.com/api/#escape