Regex cheatsheet
Javascript Regex/Regular Expression cheatsheet
Regular Expression Memo & Engine Guide: NFA/DFA Automata & ReDoS Mitigation
1. Quick Overview & Core Advantages
Regular Expressions (Regex / RegExp) are formal linguistic sequences defining search patterns across strings. Ubiquitous across programming languages, text processing tools (grep, sed, awk), ingress routers, and data validation layers, regular expressions are essential for daily software engineering. However, subtle dialect differences (POSIX, PCRE, ECMAScript, Python re), backtracking mechanics, and catastrophic backtracking risks make regular expressions notoriously error-prone.
The online Regex Memo & Cheat Sheet is an authoritative, interactive developer companion designed to provide rapid syntax lookup, token breakdowns, and computational mechanics explanations across modern regex flavors.
Core Advantages & Features
- Zero-Data Leakage Architecture: Every regex pattern search, memo lookup, and test string evaluation is computed locally within your web browser’s isolated JavaScript sandbox. Proprietary enterprise source code and sensitive user data are never logged or transmitted.
- Deep Engine Breakdown: Covers differences between backtracking NFA (Nondeterministic Finite Automata), POSIX NFA, and linear-time DFA (Deterministic Finite Automata) engines.
- ReDoS (Regular Expression Denial of Service) Prevention Guide: Identifies dangerous nested quantifiers, overlapping alternatives, and evil regex patterns that cause catastrophic exponential backtracking.
- Multi-Flavor Cross-Reference: Quick side-by-side comparison of ECMAScript (JavaScript / TypeScript), PCRE (PHP, C, Apache), Python
re, Goregexp(RE2), and Javajava.util.regex.
2. Technical Under the Hood: Automata Theory & Regex Execution Engines
Pattern: /a(b|c)*d/
1. Nondeterministic Finite Automaton (NFA):
States with epsilon transitions; backtracks on failure.
[S0] --a--> [S1] --eps--> [S2] --b--> [S3] --eps--> [S1]
| ^
+---c--> [S4]+
[S1] --d--> ((S5: MATCH))
2. Deterministic Finite Automaton (DFA):
Single deterministic state transition per input character; linear time O(n).
2.1 Theoretical Foundations: Chomsky Hierarchy & Automata
In formal language theory, regular expressions define Type-3 Regular Languages in the Chomsky hierarchy. A pure regular language can be recognized by a Finite State Machine (FSM) without auxiliary memory.
Modern regex engines diverge into two primary architectural paradigms:
1. DFA Engines (Deterministic Finite Automata - e.g., Google RE2, Rust regex)
- Linear Time Guarantee: Time complexity is strictly $O(n)$, where $n$ is the length of the input text string, regardless of pattern complexity.
- Memory Overhead: Precomputes state transition tables, which can require $O(2^m)$ memory in worst-case compilation where $m$ is pattern size.
- Limitations: Cannot support backreferences (
\1) or lookaround assertions ((?=...)), because these features transcend Type-3 languages and require context-sensitive parsing.
2. NFA Engines (Traditional Backtracking - e.g., PCRE, JavaScript V8, Python, .NET)
- Expressive Power: Fully supports non-regular features including lookahead, lookbehind, possessive quantifiers, atomic groups, and backreferences.
- Backtracking Mechanism: When a subpattern fails to match, the engine rewinds to the last recorded decision point and attempts alternative branches.
- Risk: Susceptible to Catastrophic Backtracking ($O(2^n)$ exponential complexity).
2.2 The Mechanics of Catastrophic Backtracking (ReDoS)
A Regular Expression Denial of Service (ReDoS) occurs when an NFA engine processes an ambiguous pattern against a non-matching input string, causing combinatorial state explosion.
Anatomy of an “Evil Regex”
Consider the classic vulnerable pattern:
^(a+)+$
When evaluated against the string aaaaaaaaaaaaaaaaaaaaaaaaaaaa!:
- For an input of length $N$, the outer and inner quantifiers generate $2^{N-1}$ possible ways to partition the
acharacters. - Because the trailing exclamation mark
!never matches$, the NFA engine is forced to exhaustively test every single permutation before finally declaring a failure. - For $N = 30$, this requires over $1,000,000,000$ backtracking steps, locking a CPU thread at 100% utilization for several minutes.
How to Neutralize Catastrophic Backtracking
- Atomic Grouping:
(?>a+)(freezes choices once matched; prevents backtracking into group). - Possessive Quantifiers:
a++instead ofa+(does not yield matched characters). - Mutual Exclusivity: Ensure that alternative branches do not match overlapping character sets (e.g., replace
([a-zA-Z]+|\w+)with non-overlapping boundaries).
3. Comprehensive Regex Syntax Memo & Reference Table
3.1 Character Classes & Shorthand Escapes
| Token | Meaning | Detailed Description & Edge Cases |
|---|---|---|
. |
Any character | Matches any single character except line terminators (\n, \r), unless the s (dotAll) flag is enabled. |
\d |
Digit | Matches any Arabic digit [0-9]. In PCRE/Python with Unicode flag, also matches Eastern Arabic digits. |
\D |
Non-digit | Negation of \d; matches any character that is not a numeric digit ([^0-9]). |
\w |
Word character | Matches ASCII word characters: [a-zA-Z0-9_]. Notably includes the underscore, but excludes hyphens. |
\W |
Non-word | Negation of \w; matches whitespace, punctuation, and special symbols. |
\s |
Whitespace | Matches spaces, tabs, form feeds, and line breaks: [ \t\r\n\v\f]. |
\S |
Non-whitespace | Negation of \s; matches any non-whitespace character. |
[abc] |
Character set | Matches any single character enclosed in the brackets (a, b, or c). |
[^abc] |
Negated set | Matches any character not present inside the brackets. |
[a-z] |
Range | Matches any character code between the lower and upper bounds inclusive. |
3.2 Anchors & Boundaries
| Token | Meaning | Purpose & Architectural Behavior |
|---|---|---|
^ |
Start of line | Asserts position at start of input string (or start of line if m multiline flag is active). Zero-width. |
$ |
End of line | Asserts position at end of string or right before trailing newline. Zero-width. |
\b |
Word boundary | Matches at positions where one side is \w and the other side is \W or string edge. Zero-width. |
\B |
Non-boundary | Asserts that the current position is not a word boundary. Zero-width. |
\A |
Absolute start | Matches strictly at start of entire string, ignoring multiline m mode (PCRE, Python). |
\Z |
Absolute end | Matches strictly at end of entire string, ignoring multiline m mode. |
3.3 Quantifiers: Greedy, Lazy, and Possessive
| Greedy | Lazy (Reluctant) | Possessive (No backtrack) | Match Count Description |
|---|---|---|---|
* |
*? |
*+ |
0 or more times (matches as much as possible by default). |
+ |
+? |
++ |
1 or more times. |
? |
?? |
?+ |
0 or 1 time (optional element). |
{n} |
{n}? |
{n}+ |
Exactly $n$ times. |
{n,} |
{n,}? |
{n,}+ |
At least $n$ times. |
{n,m} |
{n,m}? |
{n,m}+ |
Between $n$ and $m$ times inclusive. |
3.4 Lookarounds & Assertions (Zero-Width)
| Syntax | Type | Explanation |
|---|---|---|
(?=abc) |
Positive Lookahead | Matches a position only if followed immediately by abc. Does not consume text. |
(?!abc) |
Negative Lookahead | Matches a position only if not followed by abc. Useful for password complexity checks. |
(?<=abc) |
Positive Lookbehind | Matches a position only if preceded immediately by abc. |
(?<!abc) |
Negative Lookbehind | Matches a position only if not preceded by abc. |
4. Production Architecture: ReDoS-Safe Regex Validation Pipeline
When accepting dynamic regex patterns or validating high-volume payloads in production, applications should enforce timeout controls and AST pattern analysis. Below is a TypeScript implementation of a bounded execution wrapper:
/**
* Safe Regex Execution Wrapper with Timeout Watchdog
* Guards Node.js / Browser workers against Catastrophic Backtracking
*/
export interface SafeRegexResult {
matched: boolean;
matches: RegExpMatchArray | null;
executionTimeMs: number;
}
export class SafeRegexExecutor {
/**
* Executes a regular expression with strict execution-time guards
* @param pattern Regular expression instance
* @param input Target string to evaluate
* @param timeoutMs Maximum allowable evaluation threshold (default: 50ms)
*/
public static executeWithTimeout(
pattern: RegExp,
input: string,
timeoutMs: number = 50
): Promise<SafeRegexResult> {
return new Promise((resolve, reject) => {
const startTime = performance.now();
// Check for known high-risk ReDoS patterns before execution
if (this.hasCatastrophicStructure(pattern.source)) {
return reject(new Error('Rejected: Potential catastrophic backtracking pattern detected.'));
}
try {
const matches = input.match(pattern);
const elapsed = performance.now() - startTime;
if (elapsed > timeoutMs) {
return reject(new Error(`Execution exceeded threshold limit: ${elapsed.toFixed(2)}ms`));
}
resolve({
matched: matches !== null,
matches,
executionTimeMs: elapsed,
});
} catch (err) {
reject(err);
}
});
}
/**
* Static analysis heuristic detecting nested repeating quantifiers
*/
private static hasCatastrophicStructure(regexSource: string): boolean {
// Detects constructs like (a+)+, (.*a)*, (\w+)+
const dangerousNestedQuantifier = /\([^\)]*[\+\*][^\)]*\)[\+\*]/;
return dangerousNestedQuantifier.test(regexSource);
}
}
5. Real-World Engineering Applications
5.1 Ingress API Gateway Routing & Path Rewrites
Reverse proxies (Nginx, Traefik, Envoy, AWS ALB) rely on regular expressions to inspect incoming HTTP request paths and rewrite headers:
location ~* ^/api/v[1-2]/(users|accounts)/([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$ {
proxy_pass http://user_service_upstream;
}
Accurate regex ensures microservices only receive sanitized, well-formed UUID route parameters.
5.2 Log Parsing & Observability Ingestion
Log forwarders (FluentBit, Logstash, Vector) parse unstructured Syslog and Apache access logs into structured JSON metrics using capture groups:
^(?<client_ip>\S+) \S+ (?<user>\S+) \[(?<time>[^\]]+)\] "(?<method>\S+) (?<path>\S+) HTTP/(?<http_ver>[0-9\.]+)" (?<status>\d{3}) (?<bytes>\d+)
5.3 Input Sanitization & Form Validation
Validating sensitive input fields (E.164 international telephone numbers, ISO 8601 date timestamps, Semantic Versions) before processing downstream database queries.
6. Frequently Asked Questions (FAQs)
Q1: What is the difference between greedy and lazy matching?
A greedy quantifier (*, +) consumes as many characters as possible and only gives them back if subsequent parts of the expression fail. A lazy quantifier (*?, +?) consumes as few characters as possible, expanding one character at a time only when subsequent pattern requirements force it to do so.
Q2: Why does Google’s RE2 engine disallow backreferences?
Google developed the RE2 engine specifically for mission-critical infrastructure to guarantee that regular expressions cannot be weaponized for Denial of Service attacks. RE2 exclusively compiles regular expressions into Deterministic Finite Automata (DFA). Because backreferences (e.g., (abc)\1) require comparing dynamic captured memory states, they cannot be computed in linear time $O(n)$ by a finite automaton, and are intentionally omitted.
Q3: How do the m (multiline) and s (dotAll) flags interact?
- The
mflag modifies the behavior of anchors^and$, making them match the beginning and end of each individual line (separated by\n), rather than only the beginning and end of the entire input string. - The
s(single-line or dotAll) flag modifies the dot.metacharacter, allowing it to match newline characters (\n,\r), which it normally skips.
Q4: Why is it bad practice to parse full HTML with regular expressions?
HTML is a context-free grammar with arbitrarily nested tags, whereas regular expressions are mathematically designed for regular (Type-3) grammars. Attempting to parse nested structures like <div><div>...</div></div> with regex leads to unmaintainable, brittle expressions that break on comments, self-closing tags, and script contents. Dedicated DOM parsers (such as Cheerio, BeautifulSoup, or native browser DOMParser) should always be used instead.
7. Client-Side Privacy & Security Guarantee
This Regular Expression Memo & Engine Guide operates 100% within your client browser. Any tested regex patterns, sample search text, proprietary code snippets, and confidential strings remain strictly in local RAM. No regex patterns or string payloads are ever uploaded to external servers, providing full confidentiality and GDPR/SOC 2 compliance for enterprise software engineers.