我只是想从任何可能的字符串中创建一个正则表达式。
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 = function(s) {
return s.replace(/[$-\/?[-^{|}]/g, '\\$&');
}
这包括%、&、'和,等非元字符,但JavaScript RegExp规范允许这样做。
其他回答
我借用了上面bobince的答案,创建了一个带标签的模板函数,用于创建RegExp,其中部分值被转义,部分值不被转义。
regex-escaped.js
RegExp.escape = text => text.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&'); RegExp.escaped = flags => function (regexStrings, ...escaped) { const source = regexStrings .map((s, i) => // escaped[i] will be undefined for the last value of s escaped[i] === undefined ? s : s + RegExp.escape(escaped[i].toString()) ) .join(''); return new RegExp(source, flags); }; function capitalizeFirstUserInputCaseInsensitiveMatch(text, userInput) { const [, before, match, after ] = RegExp.escaped('i')`^((?:(?!${userInput}).)*)(${userInput})?(.*)$`.exec(text); return `${before}${match.toUpperCase()}${after}`; } const text = 'hello (world)'; const userInput = 'lo (wor'; console.log(capitalizeFirstUserInputCaseInsensitiveMatch(text, userInput));
对于TypeScript的粉丝们…
global.d.ts
interface RegExpConstructor {
/** Escapes a string so that it can be used as a literal within a `RegExp`. */
escape(text: string): string;
/**
* Returns a tagged template function that creates `RegExp` with its template values escaped.
*
* This can be useful when using a `RegExp` to search with user input.
*
* @param flags The flags to apply to the `RegExp`.
*
* @example
*
* function capitalizeFirstUserInputCaseInsensitiveMatch(text: string, userInput: string) {
* const [, before, match, after ] =
* RegExp.escaped('i')`^((?:(?!${userInput}).)*)(${userInput})?(.*)$`.exec(text);
*
* return `${before}${match.toUpperCase()}${after}`;
* }
*/
escaped(flags?: string): (regexStrings: TemplateStringsArray, ...escapedVals: Array<string | number>) => RegExp;
}
在另一个答案中链接的函数是不够的。它不能转义^或$(字符串的开始和结束),或-,在字符组中用于范围。
使用这个函数:
function escapeRegex(string) {
return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
}
虽然乍一看似乎没有必要,但转义-(以及^)使函数适合转义插入字符类以及正则表达式体中的字符。
转义/使函数适合转义在JavaScript正则表达式文字中使用的字符,以供以后计算。
由于转义它们都没有任何缺点,因此转义以覆盖更广泛的用例是有意义的。
是的,这不是标准JavaScript的一部分,这是一个令人失望的失败。
对于任何使用Lodash的人来说,自从v3.0.0以来,_.escapeRegExp函数是内置的:
_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'
而且,如果您不想需要完整的Lodash库,您可能只需要该函数!
在jQuery UI的自动完成小部件(版本1.9.1)中,他们使用了一个略有不同的正则表达式(第6753行),下面是正则表达式与bobince方法的结合。
RegExp.escape = function( value ) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
在https://github.com/benjamingr/RexExp.escape/上有一个RegExp.escape的ES7提议,在https://github.com/ljharb/regexp.escape上有一个polyfill可用。