I just want to create a regular expression out of any possible string.
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
Is there a built-in method for that? If not, what do people use? Ruby has RegExp.escape. I don't feel like I'd need to write my own, there have got to be something standard out there.
21 Answers 21
The function linked in another answer is insufficient. It fails to escape ^ or $ (start and end of string), or -, which in a character group is used for ranges.
Use this function:
function escapeRegex(string) {
return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
}
While it may seem unnecessary at first glance, escaping - (as well as ^) makes the function suitable for escaping characters to be inserted into a character class as well as the body of the regex.
Escaping / makes the function suitable for escaping characters to be used in a JavaScript regex literal for later evaluation.
As there is no downside to escaping either of them, it makes sense to escape to cover wider use cases.
And yes, it is a disappointing failing that this is not part of standard JavaScript.
33 Comments
/ at allquotemeta (\Q), Python re.escape, PHP preg_quote, Ruby Regexp.quote...var e = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g; and then your function is return s.replace(e, '\\$&'); This way you only instantiate the RegExp once.For anyone using Lodash, since v3.0.0 a _.escapeRegExp function is built-in:
_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'
And, in the event that you don't want to require the full Lodash library, you may require just that function!
6 Comments
escapeRegExp function.Most of the expressions here solve single specific use cases.
That's okay, but I prefer an "always works" approach.
function regExpEscape(literal_string) {
return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}
This will "fully escape" a literal string for any of the following uses in regular expressions:
- Insertion in a regular expression. E.g.
new RegExp(regExpEscape(str)) - Insertion in a character class. E.g.
new RegExp('[' + regExpEscape(str) + ']') - Insertion in integer count specifier. E.g.
new RegExp('x{1,' + regExpEscape(str) + '}') - Execution in non-JavaScript regular expression engines.
Special Characters Covered:
-: 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.
Notes:
/is not strictly necessary in any flavor of regular expression. However, it protects in case someone (shudder) doeseval("/" + pattern + "/");.,ensures that if the string is meant to be an integer in the numerical specifier, it will properly cause a RegExp compiling error instead of silently compiling wrong.#, and\sdo not need to be escaped in JavaScript, but do in many other flavors. They are escaped here in case the regular expression will later be passed to another program.
If you also need to future-proof the regular expression against potential additions to the JavaScript regex engine capabilities, I recommend using the more paranoid:
function regExpEscapeFuture(literal_string) {
return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}
This function escapes every character except those explicitly guaranteed not be used for syntax in future regular expression flavors.
For the truly sanitation-keen, consider this edge case:
var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');
This should compile fine in JavaScript, but will not in some other flavors. If intending to pass to another flavor, the null case of s === '' should be independently checked, like so:
var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
8 Comments
/ doesn't need to be escaped in the [...] character class.Mozilla Developer Network's Guide to Regular Expressions provides this escaping function:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
Comments
There is an ES7 proposal for RegExp.escape at https://github.com/benjamingr/RexExp.escape/, with a polyfill available at https://github.com/ljharb/regexp.escape.
4 Comments
RegExp.escape will soon be a part of official JavaScript (ECMAScript). You can start using the reference implementation here: npmjs.com/package/regexp.escape. Track the progress of the inclusion of this function in major runtimes here: github.com/tc39/proposal-regex-escaping/issues/58. Read the spec here: tc39.es/proposal-regex-escaping. WebKit has already accepted the PR.In jQuery UI's autocomplete widget (version 1.9.1) they use a slightly different regular expression (line 6753), here's the regular expression combined with bobince's approach.
RegExp.escape = function( value ) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
4 Comments
, (which is not a metacharacter), and # and whitespace which only matter in free-spacing mode (which is not supported by JavaScript). However, they do get it right not to escape the the forward slash.$.ui.autocomplete.escapeRegex(myString).Nothing should prevent you from just escaping every non-alphanumeric character:
usersString.replace(/(?=\W)/g, '\\');
You lose a certain degree of readability when doing re.toString() but you win a great deal of simplicity (and security).
According to ECMA-262, on the one hand, regular expression "syntax characters" are always non-alphanumeric, such that the result is secure, and special escape sequences (\d, \w, \n) are always alphanumeric such that no false control escapes will be produced.
4 Comments
.replace(/[^\w]/g, '\\$&') would work in the same way.new RegExp('🍎'.replace(/(?=\W)/g, '\\'), 'u') throws exception because \W matches each code unit of a surrogate pair separately, resulting in invalid escape codes..replace(/\W/g, "\\$&");There is an ES7 proposal for RegExp.escape at https://github.com/benjamingr/RexExp.escape/, with a polyfill available at https://github.com/ljharb/regexp.escape.
An example based on the rejected ES proposal, includes checks if the property already exists, in the case that TC39 backtracks on their decision.
Code:
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
};
}
Code Minified:
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');
There is also an npm module at:
https://www.npmjs.com/package/regexp.escape
One can install this and use it as so:
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');
In the GitHub && NPM page are descriptions of how to use the shim/polyfill for this option, as well. That logic is based on return RegExp.escape || implementation;, where implementation contains the regexp used above.
The NPM module is an extra dependency, but it also make it easier for an external contributor to identify logical parts added to the code. ̄\(ツ)/ ̄
2 Comments
RegExp.escape will soon be a part of official JavaScript (ECMAScript). You can start using the reference implementation here: npmjs.com/package/regexp.escape. Track the progress of the inclusion of this function in major runtimes here: github.com/tc39/proposal-regex-escaping/issues/58. Read the spec here: tc39.es/proposal-regex-escaping. WebKit has already accepted the PR.Another (much safer) approach is to escape all the characters (and not just a few special ones that we currently know) using the unicode escape format \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}'
Please note that you need to pass the u flag for this method to work:
var expression = new RegExp(escapeRegExp(usersString), 'u');
1 Comment
This is a shorter version.
RegExp.escape = function(s) {
return s.replace(/[$-\/?[-^{|}]/g, '\\$&');
}
This includes the non-meta characters of %, &, ', and ,, but the JavaScript RegExp specification allows this.
9 Comments
. is missed. And (). Or not? [-^ is strange. I don't remember what is there.XRegExp has an escape function:
XRegExp.escape('Escaped? <.>');
// -> 'Escaped\?\ <\.>'
More on: http://xregexp.com/api/#escape
Comments
escapeRegExp = function(str) {
if (str == null) return '';
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\1ドル');
};
Comments
Rather than only escaping characters which will cause issues in your regular expression (e.g.: a blacklist), consider using a whitelist instead. This way each character is considered tainted unless it matches.
For this example, assume the following expression:
RegExp.escape('be || ! be');
This whitelists letters, number and spaces:
RegExp.escape = function (string) {
return string.replace(/([^\w\d\s])/gi, '\\1ドル');
}
Returns:
"be \|\| \! be"
This may escape characters which do not need to be escaped, but this doesn't hinder your expression (maybe some minor time penalties - but it's worth it for safety).
1 Comment
RegExp.escape will soon be a part of official JavaScript (ECMAScript).
It's in Firefox and WebKit (Safari) already.
Specification: https://tc39.es/proposal-regex-escaping
Reference Implementation: https://npmjs.com/package/regexp.escape
Spec acceptance progress:
https://github.com/tc39/proposal-regex-escaping/issues/58
2 Comments
The functions in the other answers are overkill for escaping entire regular expressions (they may be useful for escaping parts of regular expressions that will later be concatenated into bigger regexps).
If you escape an entire regexp and are done with it, quoting the metacharacters that are either standalone (., ?, +, *, ^, $, |, \) or start something ((, [, {) is all you need:
String.prototype.regexEscape = function regexEscape() {
return this.replace(/[.?+*^$|({[\\]/g, '\\$&');
};
And yes, it's disappointing that JavaScript doesn't have a function like this built-in.
7 Comments
(text)next and insert it in: (?: + input + ). Your method will give the resulting string (?:\(text)next) which fails to compile. Note that this is quite a reasonable insertion, not some crazy one like re\ + input + re (in this case, the programmer can be blamed for doing something stupid))There has only ever been and ever will be 12 meta characters that need to be escaped to be considered a literal.
It doesn't matter what is done with the escaped string, inserted into a balanced regex wrapper or appended. It doesn't matter.
Do a string replace using this
var escaped_string = oldstring.replace(/[\\^$.|?*+()[{]/g, '\\$&');
4 Comments
]?I borrowed bobince's answer above and created a tagged template function for creating a RegExp where part of the value is escaped and part isn't.
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));
For our TypeScript fans...
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;
}
1 Comment
The official implementation is here:
RegExp.escape()
As of July 2025 it is available in all major browsers. Learn more at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/escape.
Comments
This one is the permanent solution.
function regExpEscapeFuture(literal_string) {
return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}
Comments
Just published a regex escape gist based on the RegExp.escape shim which was in turn based on the rejected RegExp.escape proposal. Looks roughly equivalent to the accepted answer except it doesn't escape - characters, which seems to be actually fine according to my manual testing.
Current gist at the time of writing this:
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, '\\$&')
}
1 Comment
Here is a replaceAll version.
Uses the string.includes function and a ternary to add the escape backslash instead of a regex.
const escapeRegexNonRegex = s => s.split('').map(a => "/-^$*+?.|()[]{}".includes(a) ? "\\" + a : a).join('');
const escapeRegex = s => s.replaceAll(/./g, a => "/-^$*+?.|()[]{}".includes(a) ? "\\" + a : a);
const usersString = "\\/-^$*+?.|()[]{}Hello";
const escapedString = escapeRegex(usersString);
const expression = new RegExp(escapedString);
const matches = usersString.match(expression);
console.log(matches);
RegExp.escapeis currently worked on and anyone who thinks they have valuable input is very welcome to contribute. core-js and other polyfills offer it.