Regex Escaping Cheat Sheet for JavaScript, Python, JSON, and URLs
A practical regex escaping cheat sheet for moving literal text through JavaScript, Python, JSON, and URL query strings without losing backslashes.
Regex Escaping Cheat Sheet for JavaScript, Python, JSON, and URLs
Regex escaping gets confusing because "escape this string" can mean four different jobs. You might be escaping a dot so it matches a literal period, escaping a backslash so JavaScript keeps it inside a string, escaping quotes so JSON stays valid, or percent-encoding the whole thing so it can travel in a URL. Those layers look similar in code, but they are not interchangeable.
The useful question is not "is this escaped?" It is "escaped for which parser next?" If the next parser is the regex engine, protect regex metacharacters. If the next parser is a programming language string literal, protect that language's string syntax. If the next parser is JSON, use JSON string escaping. If the next parser is a URL, use percent encoding after the value is already correct.
For the pattern layer, the Toolora Regex Escape tool is the fastest way to turn literal text into a regex-safe pattern. If you are checking tokens rather than escaping user input, keep the Regex Cheatsheet open beside it.
Start With the Layer You Are Escaping
Regex escaping is for regex metacharacters. In JavaScript, Python, PCRE, and most common engines, these characters can change the meaning of a pattern:
. * + ? ^ $ { } ( ) | [ ] \
If you want those characters to match themselves, put a backslash in front of them. The input a.b becomes a\.b, so the dot stops meaning "any character." The input total (USD) becomes total \(USD\), so the parentheses stop creating a capture group.
That is only one layer. When you place a\.b inside source code, the language may consume the backslash before the regex engine ever sees it. JavaScript string literals and JSON strings both need \\. to represent the two characters backslash plus dot. Python raw strings usually let you write r"a\.b" directly, but raw strings cannot end with a single trailing backslash.
The forward slash is a special case. It is not a regex metacharacter in most engines, but it closes a JavaScript regex literal. In /docs\/v1/, the slash is escaped for JavaScript's /.../ delimiter, not for the regex engine itself.
The Cheat Sheet: JavaScript, Python, JSON, and URLs
Use this table as a "what parser reads this next?" checklist:
| Target | Use when | Example output for literal a.b? | | --- | --- | --- | | Regex pattern | You need a pattern that matches text literally | a\.b\? | | JavaScript regex literal | You are writing /.../ in JS source | /a\.b\?/ | | JavaScript string for new RegExp() | You are passing a string into RegExp | "a\\.b\\?" | | Python raw string | You are writing a pattern in Python source | r"a\.b\?" | | JSON string | You are storing the pattern as JSON | "a\\.b\\?" | | URL component | You are sending the pattern as one query value | a%5C.b%5C%3F |
The JavaScript distinction matters in real code:
// Regex literal: the regex engine receives \.
const literal = /a\.b\?/;
// String constructor: JS reads \\ as one backslash,
// then the regex engine receives \.
const constructed = new RegExp("a\\.b\\?");
In Python, prefer raw strings for handwritten patterns:
import re
pattern = r"a\.b\?"
bool(re.search(pattern, "a.b?"))
For JSON payloads and config files, use the JSON String Escape and Unescape Tool for Developers rather than manually counting backslashes. For query parameters, encode the final value with the URL Encoder / Decoder. Do not URL-encode first and then try to regex-escape the percent signs; that creates a pattern for the encoded text, not the original text.
A Real Input Through Four Outputs
I tested the same input in Node 24.14.0 and Python 3.14.3 before writing this section because the small differences are where bugs hide. The raw text was:
price: $9.99 (USD) / refund?
Using a JavaScript escaper for the common regex metacharacters produced:
Regex pattern:
price: \$9\.99 \(USD\) / refund\?
JavaScript regex literal:
/price: \$9\.99 \(USD\) \/ refund\?/
JavaScript string for new RegExp():
"price: \\$9\\.99 \\(USD\\) / refund\\?"
JSON string containing the pattern:
"price: \\$9\\.99 \\(USD\\) / refund\\?"
URL component containing the pattern:
price%3A%20%5C%249%5C.99%20%5C(USD%5C)%20%2F%20refund%5C%3F
Python's re.escape() is valid but more aggressive in this runtime. It escaped spaces and the slash too:
Python re.escape() output:
price:\ \$9\.99\ \(USD\)\ /\ refund\?
Python JSON string containing that pattern:
"price:\\ \\$9\\.99\\ \\(USD\\)\\ /\\ refund\\?"
Both styles can match the original text. The important part is that the regex engine receives a backslash before $, ., (, ), and ?. Extra escaping before a literal space is usually harmless in Python's engine, but it can make copied patterns harder to read.
Where Escaping Stops Helping
Escaping user text prevents accidental regex syntax. It does not make every regex fast or safe. If you combine escaped text with unescaped operators, nested quantifiers, backreferences, or lookarounds, performance can still depend on the rest of the pattern.
Russ Cox's 2007 benchmark, "Regular Expression Matching Can Be Simple And Fast", is the classic warning. For the pathological pattern family a?^n a^n matched against a^n, Perl took over 60 seconds at n = 29, while a Thompson NFA implementation took about 20 microseconds. That is over 3,000,000 times faster by raw division, and Cox notes the gap keeps growing for larger inputs.
That benchmark is not saying "never use regex." It is saying that syntax choices matter. Escaping literal input removes one source of surprise: a user-supplied ?, +, (, or [ will not suddenly become control syntax. After that, review the pattern you add around it. A safe literal wrapped in a dangerous shell is still dangerous.
Practical Rules Before You Paste
Escape at the latest useful boundary. If the source value is plain user text, keep it plain as long as possible. Escape it when you build the regex pattern. JSON-escape it when you serialize JSON. URL-encode it when you build the request URL.
Never stack escapes by sight. If you see \\\\, ask what each parser consumes. In a JSON file that stores a JavaScript string that later creates a regex, four backslashes may be correct. In a plain regex tester, they probably mean you pasted the source-code form instead of the regex form.
Pick one representation for sharing. A good issue report should say: "Raw input," "regex pattern seen by the engine," and "source-code literal," separately. That avoids the common loop where one person sends \\. and another person pastes it into a regex tester expecting \.
Use the smallest tool for the current layer: regex escape for literal matching, JSON string escape for payloads, and URL encoding for query parameters. Mixing them is how the extra backslash gets born.
Made by Toolora · Updated 2026-06-06