20 regex patterns every developer should have memorized
Most developers use regex for the same 20 patterns repeatedly. The problem is that searching “email regex” returns Stack Overflow answers from 2008 that either match nothing or match everything. The patterns below are production-tested, ECMAScript-compatible, and designed for the specific tradeoff between strictness and false positives that real applications need.
All patterns below can be pasted directly into this tester. Named-group variants are included where they add value for extraction tasks.
Email and URL patterns
1. Email (practical, not RFC 5321) — The full RFC 5321 email specification allows formats like "John Doe"@example.com that no real mail server sends. For UI validation, use a practical pattern:
[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,} 2. URL (permissive, for extraction from text) — Extracts HTTP and HTTPS URLs from prose. Not for strict validation — for strict validation, use new URL(input) and catch the TypeError.
https?:\/\/[^\s]+ 3. URL with named groups (for parsing) — When you need the protocol, host, path, and query string separately:
(?<protocol>https?)://(?<host>[^\/?#]+)(?<path>[^?#]*)(?:\?(?<query>[^#]*))? IDs and identifiers
4. UUID v4 — Validates or extracts standard hyphenated UUIDs. Use case-insensitive flag:
[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12} 5. Semver with named groups — Parses semantic version strings. The named-group variant lets you extract major/minor/patch directly:
\bv?(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<prerelease>[\w.]+))?\b 6. URL slug validation — Validates that a string is a valid URL slug (lowercase, hyphens only, no leading/trailing hyphens):
^[a-z0-9]+(?:-[a-z0-9]+)*$ 7. camelCase / PascalCase identifier — Matches valid JavaScript/TypeScript identifiers in camelCase or PascalCase:
\b[a-zA-Z][a-zA-Z0-9]*(?:[A-Z][a-z0-9]+)*\b Network patterns
8. IPv4 address — Properly constrained: only 0–255 per octet. A naive \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} matches 999.999.999.999:
\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b 9. Hostname / domain — Matches RFC 1123 hostnames including subdomains:
(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,} Dates and timestamps
10. ISO 8601 date (YYYY-MM-DD) with named groups:
(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01]) 11. ISO 8601 datetime with timezone — Matches 2026-05-19T14:30:00Z and 2026-05-19T14:30:00+05:30:
\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+\-]\d{2}:\d{2}) Code patterns
12. Hex color — Matches 3, 4, 6, and 8-digit hex color codes:
#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b 13. Environment variable reference — Matches $MY_VAR, ${MY_VAR} and process.env.MY_VAR forms:
(?:\$\{?|process\.env\.)([A-Z][A-Z0-9_]*)\}? 14. ES module import path — Extracts the module specifier from import statements:
(?:import|from)\s+['"](?<module>[^'"]+)['"] Log parsing and error fingerprinting
Log parsing is where regex earns its keep in production systems. Tools like Sentry use regex patterns directly in their issue grouping rules — if you can write the pattern here, you can paste it into Sentry’s fingerprinting config and group related errors automatically.
15. Log level prefix — Matches [ERROR], [WARN], [INFO], [DEBUG]:
\[(?<level>ERROR|WARN|INFO|DEBUG|TRACE)\] 16. Stack trace frame (Node.js) — Extracts file, line, and column from Node.js stack frames like at Object.handler (/app/routes/user.js:42:17):
at\s+\S+\s+\((?<file>[^:]+):(?<line>\d+):(?<col>\d+)\) 17. PostgreSQL error code — Extracts SQLSTATE codes from Postgres error messages:
ERROR:\s+(?<message>[^\n]+)\n.*?SQLSTATE:\s+(?<code>[A-Z0-9]{5}) Sentry lets you write regex-based fingerprinting rules so that related errors — same pattern, different dynamic values — group into one issue instead of thousands. The pattern you test above can go directly into a Sentry fingerprinting config.
Try Sentry free — error monitoring with regex grouping →Named groups and how to use them in production
Named capture groups — introduced in ES2018 — are one of the most underused regex features in JavaScript. Instead of referencing groups by position (match[1], match[2]), you give them names and access them at match.groups.name.
The advantages in production code are significant. Positional groups break silently when you add a new group before an existing one. Named groups are explicit and self-documenting. They also survive refactoring: if you need to reorder groups, the code that reads match.groups.year still works.
// Positional (fragile — adding a group before year breaks this)
const [, year, month, day] = /(\d{4})-(\d{2})-(\d{2})/.exec(date);
// Named groups (robust — order does not matter)
const { year, month, day } = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/.exec(date).groups; In replace operations, reference named groups with $<name>. To reformat a date from YYYY-MM-DD to DD/MM/YYYY:
const reformat = (s) =>
s.replace(
/(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])/g,
'$<day>/$<month>/$<year>'
);
reformat('Release 2026-05-19'); // → 'Release 19/05/2026' Lookaheads and lookbehinds
Lookaheads and lookbehinds let you match a position based on what comes before or after — without including that context in the match. They are zero-width assertions: they consume no characters.
There are four variants:
(?=pattern)— Positive lookahead: match if followed by pattern(?!pattern)— Negative lookahead: match if NOT followed by pattern(?<=pattern)— Positive lookbehind: match if preceded by pattern(?<!pattern)— Negative lookbehind: match if NOT preceded by pattern
Practical example: extract API key values from an env file, but only the values — not the key names:
// Only match the value (after =), not the key name
// Input: API_KEY=sk_live_abc123
// Pattern:
(?<=\w+=)[^\s]+
// Matches: sk_live_abc123 (not API_KEY) Catastrophic backtracking and how to avoid it
Catastrophic backtracking (also called ReDoS — Regular Expression Denial of Service) occurs when a regex takes exponential time on certain inputs. It’s responsible for production outages at Cloudflare, Stack Overflow, and others.
The canonical vulnerable pattern is nested quantifiers — a quantifier inside another quantifier, both matching the same characters:
// VULNERABLE — nested quantifiers on overlapping character classes
^(a+)+$
// Test this with: aaaaaaaaaaaaaaaaaaaaaaaaaaab
// The engine tries exponentially many combinations before failing. Rules that prevent ReDoS:
- Never nest quantifiers on overlapping character classes
- Add length checks before applying expensive regexes to user input
- Prefer specific character classes over
.*in the middle of a pattern - Use the
re2npm package for high-throughput server-side parsing (linear-time engine) - Test with adversarial inputs — strings designed to cause backtracking — before shipping
For user-facing validation (form fields, CMS inputs) the risk is manageable because input is length-bounded. For server-side processing of arbitrary text, prefer RE2 or add explicit input length limits.
Debugging regex failures in production? Sentry captures the full request context — headers, body, and stack trace — so you can reproduce the exact string that caused a match to fail or catastrophically backtrack. Free for small teams.
Start using Sentry free →Frequently Asked Questions
What regex engine does this tester use?
This tester uses the browser's built-in ECMAScript regex engine — the same engine that powers JavaScript's RegExp. It supports all ES2024 features including named capture groups (?<name>...), lookaheads (?=...) and lookbehinds (?<=...), the s (dotAll) flag, the u (unicode) flag, and the d (indices) flag in modern browsers. It does NOT support PCRE-specific syntax like (?P<name>...) or possessive quantifiers — those are Perl/Python/PHP conventions.
How do named capture groups work?
Named groups use the syntax (?<name>pattern). After a match, the group's value is accessible at match.groups.name. Example: the pattern (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) applied to '2026-05-19' produces groups { year: '2026', month: '05', day: '19' }. In replace mode, reference a named group with $<name> — e.g. replace with $<day>/$<month>/$<year> to reformat the date.
What does the g (global) flag do?
Without the g flag, exec() finds only the first match. With g, the tester iterates through all non-overlapping matches in the string. For most use cases — extracting all emails from a log file, replacing all slugs — you want g enabled. Turn it off when testing whether a string matches a pattern as a whole, like validating a UUID format (where you want exactly one match covering the whole string, often combined with anchors ^ and $).
Why do I need to escape backslashes in the pattern input?
In a regex literal like /\d+/ in source code, the backslash is already part of the regex syntax. When you type a pattern into an input field, you're working with a string that gets passed to new RegExp(). In that context, \d requires two characters — a backslash and a d — which means typing \d in the box. This tester works with the raw string you type, so type \d to match a digit, \w to match a word character, and so on. The Quick Pattern library shows patterns pre-escaped for direct paste.
What is the difference between ^ and \b in anchoring?
^ matches the start of the string (or start of a line with the m flag). \b matches a word boundary — the position between a word character (\w) and a non-word character. Use ^ and $ when you want to validate an entire string (e.g. ^[a-z0-9-]+$ to validate a URL slug). Use \b when you want to find a word within surrounding text without anchoring to the start or end (e.g. \bv?\d+\.\d+\.\d+\b to find semver versions inside a changelog).
Can I use this tester for log parsing patterns?
Yes — log parsing is one of the most common production regex use cases. Common patterns: \[(ERROR|WARN|INFO)\] matches log level prefixes; (?<ip>\d{1,3}(?:\.\d{1,3}){3}) extracts IPv4 addresses from access logs; (?<ts>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}) pulls ISO timestamps. Paste a sample log line into the test string, build your pattern, then copy the named-group output directly into your parsing code. Sentry's issue grouping rules also accept regex patterns for custom fingerprinting — the same pattern you test here works there.