我只是想从任何可能的字符串中创建一个正则表达式。
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的部分可能有用)。
如果转义整个regexp并使用它,则引用独立的元字符(。, ?, +, *, ^, $, |, \) 或开始 ((, [, {) 是你所需要的:
String.prototype.regexEscape = function regexEscape() {
return this.replace(/[.?+*^$|({[\\]/g, '\\$&');
};
是的,JavaScript没有这样的内置函数是令人失望的。
其他回答
在https://github.com/benjamingr/RexExp.escape/上有一个RegExp.escape的ES7提议,在https://github.com/ljharb/regexp.escape上有一个polyfill可用。
刚刚发布了一个基于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, '\\$&')
}
escapeRegExp = function(str) {
if (str == null) return '';
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
我借用了上面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;
}
过去和将来只有12个元字符需要转义 被认为是字面上的
对转义字符串做什么并不重要,插入到平衡的正则表达式包装器或追加。没关系。
字符串替换使用这个吗
var escaped_string = oldstring.replace(/[\\^$.|?*+()[{]/g, '\\$&');