Back to blog

10 Regex Patterns Every Developer Should Know

From email validation to URL extraction — ten battle-tested regular expressions with explanations, edge cases, and copy-paste-ready snippets.

Published September 8, 2026· by TextOpal Team· 4 min read
regexdeveloper-toolsvalidation

Regular expressions are one of those tools that every developer uses reluctantly and few ever fully master. The syntax is dense, the engine quirks are many, and the moment you think you understand a pattern, some edge case breaks it. But for the right problems — input validation, log parsing, text extraction — regex is still the most efficient tool we have.

Here are ten patterns that come up again and again, with notes on what they actually match (and what they don't).

1. Email addresses (RFC 5322 simplified)

/^[^\s@]+@[^\s@]+\.[^\s@]+$/

This deliberately loose pattern catches 99% of email-shaped strings without trying to validate the full RFC 5322 grammar (which requires a several-kilobyte regex and still doesn't guarantee deliverability). It rejects the obviously bad inputs (foo, foo@, @bar.com, foo bar@baz.com) and accepts everything that looks like an email.

The full RFC 5322 regex exists but is overkill for client-side validation. Use this for the client, then send a verification email to confirm the address actually works.

2. URLs with protocol

/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g

Matches HTTP and HTTPS URLs, including optional www, optional path, optional query string. Doesn't match ftp:// or other schemes — adjust the protocol prefix if you need them.

3. Phone numbers (international)

/\+?[\d\s().-]{7,}/g

Phone numbers are notoriously hard to validate globally. Different countries use different formats, lengths, and separators. This permissive pattern catches anything that looks like a phone number — at least 7 digits, optional + prefix, allowing spaces, hyphens, parentheses, and dots. For stricter validation, use libphonenumber.

4. IPv4 addresses

/\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/g

Each octet matches 0-255 with proper bounds checking. The \b word boundaries prevent matching inside longer number sequences like 1234.5678.9012.3456.

5. Hex color codes

/^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/

Matches both 3-digit (#fff) and 6-digit (#ffffff) hex colors, with or without the # prefix. For 8-digit RGBA colors (with alpha), extend to {8}|{6}|{3}.

6. Strong password validation

/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).{12,}$/

At least 12 characters, with at least one lowercase, one uppercase, one digit, and one symbol. The lookahead assertions (?=...) don't consume characters — they just require that the pattern appears somewhere in the string.

Note: this checks the shape of a strong password, not the strength. A 12-character password matching this pattern could still be Password123!. For actual strength estimation, use zxcvbn.

7. Date in ISO 8601 format

/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?$/

Matches 2026-09-15 and 2026-09-15T14:30:00Z and 2026-09-15T14:30:00.123+05:30. Doesn't validate that the date actually exists (February 31st matches fine), but catches the format.

8. Credit card numbers (with optional separators)

/\b(?:\d[ -]*?){13,16}\b/g

Matches 13-16 digit numbers, optionally separated by spaces or hyphens. Doesn't validate the Luhn checksum — for that, you'll want a small function after regex extraction. Also doesn't restrict to known card IIN ranges, so it'll match any 16-digit number.

9. HTML tags (simple)

/<\/?[a-zA-Z][^>]*>/g

Matches opening and closing HTML tags. The [^>]* is a simplification — it breaks on tags containing > inside attribute values, which is valid HTML but rare in practice. For real HTML parsing, use a proper parser, not regex.

10. Hashtags

/(^|\s)#(\w+)/g

Matches #hashtag preceded by either start-of-string or whitespace. The capture group captures the word itself (without the #). Useful for social media text extraction.

Common regex pitfalls

Catastrophic backtracking. Patterns like (a+)+b match fine on aaaaab but explode exponentially on aaaaaaaaaaaaaaaaaaaa!. Modern engines have mitigations, but if your regex takes 30 seconds to run on a 100-character input, you've hit this.

Greedy quantifiers eating too much. .* matches as much as possible. .*? matches as little as possible. When parsing HTML with regex (which you shouldn't, but sometimes must), <.*> on <b>bold</b> <i>italic</i> matches the entire string in one go. <[^>]*> is safer.

Forgetting the global flag. Without g, .match() returns only the first match. With g, it returns all matches but loses capture groups. Use .matchAll() for both.

Backreferences in lookahead. Some engines support (?=(foo))\1 to assert and capture simultaneously. JavaScript supports this since 2018, but older runtimes don't.

Testing regex locally

Every developer who works with regex regularly needs a local tester — pasting patterns and test strings into online tools leaks whatever data you're debugging. TextOpal's Regex Tester runs JavaScript's native regex engine in your browser, with real-time match highlighting, capture group extraction, and safe caps on input size. Patterns never leave your device.

The regex mindset

The best regex is often the simplest one that solves the problem. Resist the temptation to write a single mega-pattern that handles every edge case — extract, validate, and parse in stages. A 10-line function with three small regexes is almost always easier to maintain than one 200-character pattern that does it all.

Regex is a tool, not a religion. Use it when it fits, and reach for a real parser when the input is genuinely structured (HTML, JSON, XML). The patterns above cover about 80% of everyday validation tasks. The other 20% is where the real work begins.

Try the tool

Regex Tester Online

Related articles

TextOpal home