我只想从任何可能的字符串中创建一个正则表达式。
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
有没有内置的方法?如果不是,人们用什么?Ruby有RegExp.escape
。我不觉得我需要自己写,那里必须有一些标准的东西。
我只想从任何可能的字符串中创建一个正则表达式。
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
有没有内置的方法?如果不是,人们用什么?Ruby有RegExp.escape
。我不觉得我需要自己写,那里必须有一些标准的东西。
另一个答案中链接的功能不足。它无法转义^
or $
(字符串的开头和结尾)或-
,它在字符组中用于范围。
使用这个功能:
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
虽然乍一看似乎没有必要,但转义-
(以及^
)使该函数适合转义要插入字符类以及正则表达式主体的字符。
转义/
使该函数适用于转义要在 JavaScript 正则表达式文字中使用的字符以供以后评估。
由于逃避它们中的任何一个都没有缺点,因此逃避以涵盖更广泛的用例是有意义的。
是的,这不是标准 JavaScript 的一部分,这是一个令人失望的失败。
对于任何使用 Lodash 的人,从 v3.0.0开始,内置了一个_.escapeRegExp函数:
_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'
这里的大多数表达式都解决了单个特定用例。
没关系,但我更喜欢“始终有效”的方法。
function regExpEscape(literal_string) {
return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}
这将“完全转义”正则表达式中以下任何用途的文字字符串:
new RegExp(regExpEscape(str))
new RegExp('[' + regExpEscape(str) + ']')
new RegExp('x{1,' + regExpEscape(str) + '}')
涵盖的特殊字符:
-
: 在字符类中创建字符范围。[
/ ]
:开始/结束一个字符类。{
/ }
:开始/结束一个数字说明符。(
/ )
:开始/结束一个组。*
/ +
/ ?
:指定重复类型。.
: 匹配任何字符。\
: 转义字符,并启动实体。^
: 指定匹配区域的开始,并否定字符类中的匹配。$
: 指定匹配区域的结束。|
: 指定交替。#
: 在自由间距模式下指定注释。\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) : '') + ')');
Mozilla 开发者网络的正则表达式指南提供了这个转义函数:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
在 jQuery UI 的自动完成小部件(1.9.1 版)中,它们使用了稍微不同的正则表达式(第 6753 行),这里是结合bobince 方法的正则表达式。
RegExp.escape = function( value ) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}