Escaping metacharacters: which ones, and where
A backslash turns a metacharacter into a literal. Outside a character class twelve characters need it; inside one only the closing bracket, caret, hyphen and backslash do.
At a glance
- Escape outside a class
- ^ $ . * + ? ( ) [ ] { } | and the backslash itself
- Also in a regex literal
- the forward slash, written as \/
- Escape inside a class
- only ] ^ - and the backslash
- Escaping a letter
- changes its meaning, \b and \d are not a literal b and d
- With the u flag
- escaping a character that needs no escape becomes a SyntaxError
- User input
- run it through an escape function before new RegExp
In detail
The list of characters that need a backslash outside a character class is short and worth memorising: the two anchors, the dot, the three quantifier symbols, both kinds of bracket, both braces, the pipe and the backslash itself. In a regex literal the forward slash also needs escaping, because it would otherwise close the literal, but that is a syntax of the source file rather than of the pattern.
Inside a character class the list collapses to four. A dot, a plus, a star, a pipe and a pair of parentheses are all literal in there, which is why building a class of punctuation is so much easier than escaping the same characters one at a time. Only the closing bracket, the caret in first position, the hyphen between two characters and the backslash retain any special meaning.
Escaping a letter does the opposite of what escaping punctuation does. A backslash before punctuation removes meaning; a backslash before a letter usually adds it. \b, \d, \s and \w are all escapes with their own behaviour, and \q is a literal q only because of a legacy compatibility rule that the u flag removes. Under u, escaping something that did not need it is an error.
None of this can be done by hand when the pattern is built from user input. A search box that drops the typed text straight into new RegExp will throw on an unbalanced bracket, match the wrong thing on a dot, and hang on a well chosen nested quantifier. A four line escape function applied to the input first removes all three problems.
Examples
function escapeRegex(s) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
escapeRegex("1+1 (=2)"); // "1\\+1 \\(=2\\)"
new RegExp("a.b").test("axb"); // true, the dot is a wildcard
new RegExp(escapeRegex("a.b")).test("axb"); // false
new RegExp(escapeRegex("a.b")).test("a.b"); // trueThe $& in the replacement inserts whatever the class matched, so each special character is prefixed with its own backslash.
/[.+*]/.exec("a+b")[0]; // "+", no escaping needed
/[\]]/.test("]"); // true, the closing bracket is the exception
new RegExp("\\q").test("q"); // true, a legacy rule makes it literal
new RegExp("\\q", "u"); // SyntaxError: Invalid escapeThings that catch people out
- Dropping user input straight into new RegExp is a correctness bug and a denial of service risk at the same time. An unbalanced bracket throws, a dot matches too much, and a nested quantifier can hang the process.
- Escaping a letter changes its meaning rather than removing it, so a blanket escape function that touches letters produces \d and \b where the user typed d and b.
- Under the u flag an unnecessary escape is a syntax error, so an escape function that is too aggressive breaks the moment someone adds the flag.
Try it: Regex Tester
Type a pattern and a test string, watch every match highlight as you go, read a plain English breakdown of each token, and check the numbered and named groups it captured.
Regex Tester
LOCAL · Browser-OnlyTest and debug regular expressions with live matching and highlights
Related Regex syntax
All regex syntax →[abc]: character sets and what loses its meaning inside
A bracket set matches one character from a list. Most metacharacters go literal inside it, and only four keep any special meaning at all.
The u flag: Unicode mode
What the u flag changes about how a pattern is parsed, the escape forms it unlocks, and the previously tolerated syntax it turns into a hard error.
The dot: any character except a line terminator
What the dot matches by default, the four characters it skips, how the u and s flags change it, and why it needs no escape inside a character class.
Regex for email addresses: what can and cannot be validated
No regular expression fully validates an email address. Here is what the built in preset accepts, what it rejects, and the only check that settles it.
Regex for URLs: finding links without overreaching
The built in URL preset needs a scheme and a dotted host, which rules out localhost and bare ports. It also swallows a full stop at the end of a path.
Regex for IPv4 addresses with real octet range checks
The naive four groups of digits pattern accepts 999.999.999.999. Here is the alternation that enforces 0 to 255, and the leading zero case it still allows.
Tools for this
- Regex Tester Free online regex tester - test and debug regular expressions with live matching and highlights
- AI Regex Generator Free online AI regex generator - browse 35+ common regex patterns or generate custom ones with AI
- Regex Playground Regex playground with live match highlighting, named groups, find and replace, and shareable links