我只是想从任何可能的字符串中创建一个正则表达式。
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 shim的regex转义要点,而RegExp.escape shim又是基于被拒绝的RegExp.escape提议的。看起来大致相当于公认的答案,除了它没有转义-字符,根据我的手动测试,这似乎实际上是好的。
撰写本文时的主要内容:
const syntaxChars = /[\^$\\.*+?()[\]{}|]/g
/**
* Escapes all special special regex characters in a given string
* so that it can be passed to `new RegExp(escaped, ...)` to match all given
* characters literally.
*
* inspired by https://github.com/es-shims/regexp.escape/blob/master/implementation.js
*
* @param {string} s
*/
export function escape(s) {
return s.replace(syntaxChars, '\\$&')
}
其他回答
这是一个较短的版本。
RegExp.escape = function(s) {
return s.replace(/[$-\/?[-^{|}]/g, '\\$&');
}
这包括%、&、'和,等非元字符,但JavaScript RegExp规范允许这样做。
Mozilla开发者网络正则表达式指南提供了这个转义函数:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
过去和将来只有12个元字符需要转义 被认为是字面上的
对转义字符串做什么并不重要,插入到平衡的正则表达式包装器或追加。没关系。
字符串替换使用这个吗
var escaped_string = oldstring.replace(/[\\^$.|?*+()[{]/g, '\\$&');
与其只转义字符,否则会导致正则表达式中的问题(例如:黑名单),不如考虑使用白名单。这样每个字符都被认为是有污点的,除非它匹配。
对于本例,假设有以下表达式:
RegExp.escape('be || ! be');
白名单包括字母、数字和空格:
RegExp.escape = function (string) {
return string.replace(/([^\w\d\s])/gi, '\\$1');
}
返回:
"be \|\| \! be"
这可能会转义不需要的字符,但这不会妨碍您的表达(可能会有一些小的时间损失-但为了安全起见,这是值得的)。
另一种(更安全的)方法是使用unicode转义格式\u{code}转义所有字符(而不仅仅是我们目前知道的一些特殊字符):
function escapeRegExp(text) {
return Array.from(text)
.map(char => `\\u{${char.charCodeAt(0).toString(16)}}`)
.join('');
}
console.log(escapeRegExp('a.b')); // '\u{61}\u{2e}\u{62}'
请注意,你需要传递u标志来让这个方法工作:
var expression = new RegExp(escapeRegExp(usersString), 'u');