Javascript中是否有RegExp.escape函数?
我只是想从任何可能的string中创build一个正则expression式。
var usersString = "Hello?!*`~World()[]"; var expression = new RegExp(RegExp.escape(usersString)) var matches = "Hello".match(expression);
有没有内置的方法呢? 如果不是,人们使用什么? Ruby有RegExp.escape
。 我不觉得自己需要写自己的东西,那里就有标准。 谢谢!
上面链接的function是不够的。 它无法逃避^
或$
(string的开始和结束)或-
,在字符组中用于范围。
使用这个function:
RegExp.escape= function(s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); };
虽然乍一看似乎没有必要,但是转义(和^
)使函数适合将转义字符插入到字符类以及正则expression式的主体中。
Escaping /
使函数适合在JS regex文字中使用转义字符,以便以后使用eval。
由于逃脱其中任何一个都没有缺点,所以逃避覆盖更广泛的用例是有意义的。
是的,这是一个令人失望的失败,这不是标准的JavaScript的一部分。
对于任何使用lodash的人来说, 自v3.0.0以来内置了一个_.escapeRegExp函数:
_.escapeRegExp('[lodash](https://lodash.com/)'); // → '\[lodash\]\(https:\/\/lodash\.com\/\)'
而且,如果你不想要完整的lodash库,你可能只需要这个function !
这里的大多数expression式解决了单个特定的用例。
没关系,但我更喜欢“总是有效”的方法。
function regExpEscape(literal_string) { return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&'); }
这将在正则expression式中“完全转义”以下任何用途的文字string:
- 插入正则expression式。 例如
new RegExp(regExpEscape(str))
- 插入一个字符类。 例如
new RegExp('[' + regExpEscape(str) + ']')
- 在整数计数说明符中插入。 例如
new RegExp('x{1,' + regExpEscape(str) + '}')
- 在非JavaScript正则expression式引擎中执行。
特殊字符涵盖:
-
-
:在字符类中创build一个字符范围。 -
[
/]
:开始/结束一个字符类。 -
{
/}
:开始/结束一个数字说明符。 -
(
/)
:开始/结束一个组。 -
*
/+
/?
:指定重复types。 -
.
:匹配任何字符。 -
\
:转义字符,并启动实体。 -
^
:指定匹配区域的开始,并且否定字符类中的匹配。 -
$
:指定匹配区域的结束。 -
|
:指定交替。 -
#
:以自由间距模式指定注释。 -
\s
:以自由间距模式忽略。 -
,
:分隔数字说明符中的值。 -
/
:开始或结束expression。 -
:
完成特殊的组types和部分Perl风格的字符类。 -
!
:否定零宽度组。 -
<
/=
:零宽度组规格的一部分。
笔记:
-
/
在任何正则expression式中都不是绝对必要的。 然而,它保护万一有人(不寒而栗)确实eval("/" + pattern + "/");
。 -
,
确保如果string是数字说明符中的一个整数,它将正确地导致RegExp编译错误,而不是静默地编译错误。 -
#
,并不需要在JavaScript中转义,但在许多其他的风格。 如果正则expression式稍后会传递给另一个程序,它们将在这里被转义。
如果您还需要针对JavaScript正则expression式引擎function的潜在附加function进一步validation正则expression式,则build议使用更偏执的方法:
function regExpEscapeFuture(literal_string) { return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&'); }
除了那些明确保证不用于将来的正则expression式风格的语法之外,该函数转义每个字符。
对于真正的卫生热衷者,请考虑这个边缘情况:
var s = ''; new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');
这应该在JavaScript中编译好,但不会在其他一些风格。 如果打算传递给另一种风格,应该单独检查s === ''
的空值,如下所示:
var s = ''; new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
在jQueryUI的自动完成小部件(版本1.9.1),他们使用一个稍微不同的正则expression式(6753行),这是正则expression式结合@bobince方法。
RegExp.escape = function( value ) { return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); }
正则expression式的Mozilla开发者networking指南提供了这个转义函数:
function escapeRegExp(string){ return string.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1"); }
什么都不应该阻止你逃脱每个非字母数字字符:
usersString.replace(/(?=\W)/g, '\\');
在执行re.toString()
时,你会失去一定的可读性,但是你赢得了很多的简单性(和安全性)。
根据ECMA-262,一方面,正则expression式“语法字符”总是非字母数字的,从而结果是安全的,并且特殊的转义序列( \d
, \w
, \n
)总是字母数字的,将会产生错误的控制逃逸。
这是一个较短的版本。
RegExp.escape = function(s) { return s.replace(/[$-\/?[-^{|}]/g, '\\$&'); }
这包括%
, &
, '
和,
的非元字符,但JavaScript RegExp规范允许这样做。
escapeRegExp = function(str){ if (str == null) return ''; return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); },
XRegExp有一个转义函数:
XRegExp.escape('Escaped? <.>'); // -> 'Escaped\?\ <\.>'
更多关于: http : //xregexp.com/api/#escape
而不是只是逃避会导致正则expression式(例如:黑名单)问题的字符,为什么不考虑使用白名单。 这样每个angular色被认为是污点,除非它匹配。
对于这个例子,假设下面的expression式:
RegExp.escape('be || ! be');
这个白名单的字母,数字和空格:
RegExp.escape = function (string) { return string.replace(/([^\w\d\s])/gi, '\\$1'); }
返回:
"be \|\| \! be"
这可能会转义字符,不需要逃跑,但这并不妨碍你的expression(也许一些小的时间处罚 – 但它是值得的安全)。
其他答案中的函数对于转义整个正则expression式来说是矫枉过正的(它们可能用于转义正则expression式的部分 ,这些正则expression式将被连接成更大的正则expression式)。
如果你逃避了整个正则expression式并且完成了它,引用单独( .
, ?
, +
, *
, ^
, $
, |
, \
)的元字符或者开始一些东西( (
, [
, {
) :
String.prototype.regexEscape = function regexEscape() { return this.replace(/[.?+*^$|({[\\]/g, '\\$&'); };
是的,这是令人失望的JavaScript没有这样的内置function。