我只是想从任何可能的字符串中创建一个正则表达式。
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。我觉得我不需要写我自己的,必须有一些标准的东西。
当前回答
与其只转义字符,否则会导致正则表达式中的问题(例如:黑名单),不如考虑使用白名单。这样每个字符都被认为是有污点的,除非它匹配。
对于本例,假设有以下表达式:
RegExp.escape('be || ! be');
白名单包括字母、数字和空格:
RegExp.escape = function (string) {
return string.replace(/([^\w\d\s])/gi, '\\$1');
}
返回:
"be \|\| \! be"
这可能会转义不需要的字符,但这不会妨碍您的表达(可能会有一些小的时间损失-但为了安全起见,这是值得的)。
其他回答
这是一个较短的版本。
RegExp.escape = function(s) {
return s.replace(/[$-\/?[-^{|}]/g, '\\$&');
}
这包括%、&、'和,等非元字符,但JavaScript RegExp规范允许这样做。
这里的大多数表达式都解决单个特定的用例。
这没关系,但我更喜欢“总是有效”的方法。
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正则表达式引擎中执行。
涉及的特殊字符:
-: 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.
注:
/在任何类型的正则表达式中都不是严格必要的。但是,如果有人(不寒而栗)执行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中应该编译得很好,但在其他类型中就不行。如果打算传递给另一个flavor,则应该单独检查s === "的空大小写,如下所示:
var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
过去和将来只有12个元字符需要转义 被认为是字面上的
对转义字符串做什么并不重要,插入到平衡的正则表达式包装器或追加。没关系。
字符串替换使用这个吗
var escaped_string = oldstring.replace(/[\\^$.|?*+()[{]/g, '\\$&');
XRegExp有一个转义函数:
XRegExp.escape(“逃?< >。'); // -> '已转义\?\ < \ >。”
更多信息:http://xregexp.com/api/#escape
在https://github.com/benjamingr/RexExp.escape/上有一个RegExp.escape的ES7提议,在https://github.com/ljharb/regexp.escape上有一个polyfill可用。