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

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

有内置的方法吗?如果不是,人们用什么?Ruby有RegExp.escape。我觉得我不需要写我自己的,必须有一些标准的东西。


当前回答

在https://github.com/benjamingr/RexExp.escape/上有一个RegExp.escape的ES7提议,在https://github.com/ljharb/regexp.escape上有一个polyfill可用。

一个基于被拒绝的ES提案的例子,包括检查属性是否已经存在,以防TC39改变他们的决定。


代码:

if (!Object.prototype.hasOwnProperty.call(RegExp, 'escape')) {
  RegExp.escape = function(string) {
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Escaping
    // https://github.com/benjamingr/RegExp.escape/issues/37
    return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
  };
}

代码简化:

Object.prototype.hasOwnProperty.call(RegExp,"escape")||(RegExp.escape=function(e){return e.replace(/[.*+\-?^${}()|[\]\\]/g,"\\$&")});

// ...
var assert = require('assert');
 
var str = 'hello. how are you?';
var regex = new RegExp(RegExp.escape(str), 'g');
assert.equal(String(regex), '/hello\. how are you\?/g');

还有一个npm模块在: https://www.npmjs.com/package/regexp.escape


你可以安装这个并这样使用它:


npm install regexp.escape

or

yarn add regexp.escape

var escape = require('regexp.escape');
var assert = require('assert');
 
var str = 'hello. how are you?';
var regex = new RegExp(escape(str), 'g');
assert.equal(String(regex), '/hello\. how are you\?/g');

在GitHub && NPM页面是如何使用shim/polyfill这个选项的描述。该逻辑基于返回regexp .escape || implementation;,其中实现包含上面使用的regexp。


NPM模块是一个额外的依赖项,但它也使外部贡献者更容易识别添加到代码中的逻辑部分。¯\()/¯

其他回答

其他答案中的函数对于转义整个正则表达式来说是多余的(它们对于转义正则表达式中稍后将连接到更大的regexp的部分可能有用)。

如果转义整个regexp并使用它,则引用独立的元字符(。, ?, +, *, ^, $, |, \) 或开始 ((, [, {) 是你所需要的:

String.prototype.regexEscape = function regexEscape() {
  return this.replace(/[.?+*^$|({[\\]/g, '\\$&');
};

是的,JavaScript没有这样的内置函数是令人失望的。

这是一个较短的版本。

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

这包括%、&、'和,等非元字符,但JavaScript RegExp规范允许这样做。

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

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

与其只转义字符,否则会导致正则表达式中的问题(例如:黑名单),不如考虑使用白名单。这样每个字符都被认为是有污点的,除非它匹配。

对于本例,假设有以下表达式:

RegExp.escape('be || ! be');

白名单包括字母、数字和空格:

RegExp.escape = function (string) {
    return string.replace(/([^\w\d\s])/gi, '\\$1');
}

返回:

"be \|\| \! be"

这可能会转义不需要的字符,但这不会妨碍您的表达(可能会有一些小的时间损失-但为了安全起见,这是值得的)。

在jQuery UI的自动完成小部件(版本1.9.1)中,他们使用了一个略有不同的正则表达式(第6753行),下面是正则表达式与bobince方法的结合。

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