Regex Patterns Every Developer Should Have: A Practical Reference
A practical reference of the regex patterns developers actually need β email, URL, UUID, IP address, dates, semver, hex colours, slugs, and more β with edge cases and caveats for each.
By sadiqbd Β· June 8, 2026
Nobody memorises regex β but some patterns are worth having close at hand
Regex gets a reputation for being write-only: you can write it in the moment but can't read it back three months later. That reputation is partly earned. A pattern like ^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@#$%^&+=]).{8,}$ is not exactly self-documenting.
But for the patterns developers actually reach for repeatedly β validating an email, matching a URL, extracting a date, checking a UUID β the regex is usually well-understood, widely tested, and worth keeping in a reference doc. This is that reference doc.
Each pattern below is tested for common inputs, includes what it matches and what it intentionally excludes, and notes edge cases worth knowing.
Email address
^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$
Matches: user@example.com, user.name+tag@sub.domain.co.uk, user123@company.io
Rejects: @example.com, user@, user@.com, user@domain
The honest caveat: fully RFC 5321-compliant email validation with regex is impractically complex. The pattern above catches the overwhelming majority of invalid inputs while accepting all common valid addresses. For anything critical, send a verification email rather than relying entirely on the pattern.
URL (http/https)
^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&\/=]*)$
Matches: https://example.com, http://sub.domain.co.uk/path?q=1&r=2, https://example.io/path#anchor
Rejects: ftp://example.com, example.com (no protocol), http:// (no host)
Note: this pattern validates structure, not reachability. A structurally valid URL may still return 404. For link validation, check the HTTP response.
IP address (IPv4)
^((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]?)$
Matches: 192.168.1.1, 10.0.0.0, 255.255.255.255, 0.0.0.0
Rejects: 256.0.0.1, 192.168.1, 192.168.1.1.1
The alternation 25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]? ensures each octet stays within 0β255. This is the key detail many simplified IP patterns miss β \d{1,3} would accept 999.999.999.999.
IPv6 address
^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$
Matches full-form IPv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
Does not match compressed form (::1, 2001:db8::1). For compressed IPv6, a complete pattern requires considerably more complexity β consider a library rather than regex for production IPv6 validation.
UUID (v4)
^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
Matches: 550e8400-e29b-41d4-a716-446655440000, f47ac10b-58cc-4372-a567-0e02b2c3d479
The v4-specific constraints: the third group starts with 4 (version), the fourth group starts with 8, 9, a, or b (variant bits)
If you only need to verify UUID format without caring about v4 specifically:
^[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}$
Date formats
ISO 8601 (YYYY-MM-DD):
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
Matches: 2024-06-15, 2000-01-01
Note: validates month (01β12) and day (01β31) ranges but doesn't check month-day validity (e.g. 2024-02-31 passes structurally).
US format (MM/DD/YYYY):
^(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/\d{4}$
Matches: 06/15/2024, 12/31/1999
European format (DD/MM/YYYY):
^(0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/\d{4}$
Time (24-hour)
^([01]\d|2[0-3]):([0-5]\d)(:[0-5]\d)?$
Matches: 09:30, 23:59, 14:30:45
Rejects: 25:00, 12:60, 9:5
Phone numbers (international)
^\+?[1-9]\d{1,14}$
This is the E.164 international standard β up to 15 digits, optional leading +, no spaces or dashes.
For display-formatted numbers (which humans actually type), the variation is enormous: +44 20 7946 0958, (212) 555-0100, 07700 900123. Stripping non-digits and validating the result is usually more robust:
^[\d\s()+\-]{7,20}$
Then strip and re-validate the digit-only string.
Credit card numbers (Luhn check with regex)
Regex can match the format but not validate the checksum (the Luhn algorithm requires arithmetic). Format patterns:
Visa: ^4[0-9]{12}(?:[0-9]{3})?$ (13 or 16 digits starting with 4)
Mastercard: ^5[1-5][0-9]{14}$ (16 digits starting with 51β55)
Amex: ^3[47][0-9]{13}$ (15 digits starting with 34 or 37)
Generic (any major card): ^[3-6]\d{13,18}$
Always combine with a Luhn checksum function for real validation.
Slug / URL path segment
^[a-z0-9]+(?:-[a-z0-9]+)*$
Matches: my-blog-post, article-2024, hello
Rejects: My-Blog-Post (uppercase), -leading-hyphen, trailing-hyphen-, double--hyphen
Hex colour code
^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
Matches: #FFF, #fff, #FF6B35, #3a86ff
Rejects: FF6B35 (no hash), #GGG (invalid hex), #FFFF (wrong length)
For 8-digit hex (with alpha):
^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$
Semantic version (semver)
^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$
This is the official semver.org pattern. It validates major, minor, patch, optional pre-release (-alpha.1), and optional build metadata (+build.123).
For basic MAJOR.MINOR.PATCH only:
^\d+\.\d+\.\d+$
JWT structure
^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$
Three Base64URL-encoded segments separated by dots. Validates structure only β not signature or claims.
Positive integer
^[1-9]\d*$
Matches: 1, 42, 1000000
Rejects: 0, -5, 3.14, 007 (leading zero)
For non-negative integer (including zero):
^(0|[1-9]\d*)$
Password strength (common policy)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@#$%^&+=!]).{8,}$
Requires: at least one lowercase, one uppercase, one digit, one special character, minimum 8 characters total.
The lookaheads ((?=...)) don't consume characters β they assert conditions. The final .{8,} matches the actual string.
Caveat: as discussed in a recent post on this blog, complexity rules like this are less effective than they appear. A random generator with sufficient length is more secure than a human-chosen string that meets these requirements.
Using these patterns in the Regex Tester on sadiqbd.com
Each pattern above can be pasted directly into the Regex Tester:
- Paste the pattern into the regex field
- Enter test strings β one per line β in the test input
- See matches highlighted in real time β green for full matches, highlighted groups for captures
- Check edge cases immediately β try inputs that should fail as well as those that should pass
The live feedback is particularly useful for patterns with lookaheads (like the password strength check) where the visual match isn't always obvious from reading the regex alone.
Tips for working with regex
Test with inputs that should fail, not just inputs that should match. A pattern that accepts everything is useless. Test your expected valid inputs, then test obvious invalid inputs, then test the edge cases close to the boundary.
Anchor your patterns. \d+ matches "one or more digits anywhere in the string." ^\d+$ matches "a string consisting entirely of digits." Forgetting anchors is a common source of regex bugs where partial matches succeed unexpectedly.
Use named capture groups for readability. (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) is far more maintainable than (\d{4})-(\d{2})-(\d{2}) when you're referencing groups by position six months later.
Regex is not the right tool for HTML. Parsing HTML with regex is famously unreliable. Use a proper HTML parser β BeautifulSoup in Python, DOMParser in browsers, Cheerio in Node.js. Same applies to nested structures like JSON.
Frequently Asked Questions
Why do some regex patterns look different across languages?
Regex flavours vary β PCRE (PHP, Python, most tools), JavaScript, .NET, and POSIX each have slight differences in syntax and features. Named capture groups use (?P<name>...) in Python but (?<name>...) in JavaScript. Lookaheads, Unicode support, and flag behaviour differ. Always test in the language you're actually using.
Are these patterns safe to use in production? The patterns above are well-tested for common use cases. For security-sensitive validation (email verification, payment data), treat them as a first filter and complement with server-side logic. Don't rely on client-side regex alone for anything with security implications.
What's a lookahead and when do I need one?
A lookahead (?=...) asserts that a position is followed by a pattern without consuming characters. It's used for conditions that must be true simultaneously β like "this string must contain at least one digit AND at least one uppercase letter." Without lookaheads, you'd need multiple separate checks.
Is the Regex Tester free? Yes β completely free, no sign-up required.
Regex is one of those skills where having a reliable reference saves more time than deep expertise. These patterns cover the 80% of cases that come up repeatedly β test them in the tester, adapt them to your specific requirements, and keep the reference close.
Try the Regex Tester free at sadiqbd.com β paste any pattern and test it against real inputs with live highlighting.