Regular expressions are the Swiss Army knife of text processing. Whether you're validating form input, parsing logs, or scraping data, having a handful of reliable regex patterns in muscle memory will save you hours every week. We've distilled thousands of real-world use cases into the 10 patterns you'll reach for most often — each one explained piece by piece so you actually understand what it does. Try every pattern live in our Regex Tester as you read along.
^[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}$
How it works: ^[\w._%+-]+ matches the local part (letters, digits, dots, underscores, percent, plus, hyphen). @ is the literal separator. [\w.-]+ matches the domain name, and \.[A-Za-z]{2,}$ enforces a valid TLD of at least two letters.
// JavaScript
const emailRe = /^[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}$/;
emailRe.test("
[email protected]"); // true
# Python
import re
re.match(r'^[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}$', '
[email protected]')
Tip: This covers ~99% of real-world addresses. For full RFC 5322 compliance you'd need a much longer pattern — but in practice this is the sweet spot of accuracy vs. readability.
https?:\/\/(?:[\w-]+\.)+[\w-]+(?:\/[\w._~:/?#\[\]@!$&'()*+,;=%-]*)?
How it works: https?:\/\/ matches the protocol. (?:[\w-]+\.)+[\w-]+ matches one or more domain segments separated by dots. The optional tail handles path, query, and fragment characters.
✓ https://example.com/path?q=1
✓ http://sub.domain.co.uk
✗ ftp://files.example.com
✗ not-a-url
// JavaScript — extract all URLs from a string
const urls = text.match(/https?:\/\/(?:[\w-]+\.)+[\w-]+(?:\/[\w._~:\/?#\[\]@!$&'()*+,;=%-]*)*/g);
# Python
urls = re.findall(r'https?://(?:[\w-]+\.)+[\w-]+(?:/[\w._~:/?#\[\]@!$&\'()*+,;=%-]*)?', text)
^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$
How it works: Each octet is validated numerically: 25[0-5] handles 250–255, 2[0-4]\d handles 200–249, and [01]?\d\d? handles 0–199. The pattern repeats for all four octets separated by literal dots.
✓ 192.168.1.1
✓ 0.0.0.0
✗ 256.1.1.1
✗ 192.168.1
Tip: A simpler \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} works for quick extraction, but won't reject invalid octets like 999. Use the full version for validation.
^(\+?\d{1,3}[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}$
How it works: The optional (\+?\d{1,3}[-.\s]?)? handles country codes like +1 or +44. (\(?\d{3}\)?[-.\s]?)? matches an area code with optional parentheses. The final \d{3}[-.\s]?\d{4} matches the seven core digits with flexible separators.
✓ (555) 123-4567
✓ +1-555-123-4567
✓ 5551234567
✗ 123-45
// JavaScript
const phoneRe = /^(\+?\d{1,3}[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}$/;
# Python — strip non-digits after validating
digits = re.sub(r'\D', '', phone_number)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
How it works: \d{4} matches a four-digit year. (0[1-9]|1[0-2]) limits months to 01–12. (0[1-9]|[12]\d|3[01]) limits days to 01–31. This doesn't catch impossible dates like Feb 30 — for that you still need programmatic validation.
✓ 2026-02-01
✓ 1999-12-31
✗ 2026-13-01
✗ 2026-00-15
// JavaScript — extract and parse
const [, y, m, d] = dateStr.match(/^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/);
# Python — named groups
m = re.match(r'^(?P<year>\d{4})-(?P<month>0[1-9]|1[0-2])-(?P<day>0[1-9]|[12]\d|3[01])$', s)
m.group('year') # '2026'
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
How it works: Four lookaheads run independently: (?=.*[a-z]) requires a lowercase letter, (?=.*[A-Z]) an uppercase, (?=.*\d) a digit, and (?=.*[@$!%*?&]) a special character. The final [A-Za-z\d@$!%*?&]{8,}$ enforces allowed characters and minimum length.
✓ P@ssw0rd!
✓ Str0ng&Pass
✗ password
✗ SHORT1!
Warning: Regex-only password validation is a starting point. Modern best practices (NIST 800-63B) favour minimum length over complexity rules. Consider checking against known breached password lists too.
<([a-z][a-z0-9]*)\b[^>]*>(.*?)<\/\1>
How it works: <([a-z][a-z0-9]*) captures the tag name. \b[^>]*> matches attributes. (.*?) lazily captures inner content. <\/\1> uses a backreference to match the corresponding closing tag.
✓ <p>Hello</p>
✓ <div class="x">Content</div>
✗ <br/> (self-closing)
Important: Never use regex to parse HTML in production. HTML is not a regular language — nested tags will defeat any regex. Use a DOM parser (DOMParser in JS, BeautifulSoup in Python). This pattern is only useful for quick-and-dirty extraction from simple, known markup.
^\s+|\s+$
How it works: ^\s+ matches leading whitespace and \s+$ matches trailing whitespace. The alternation | targets both ends. Replace with an empty string to trim.
✓ " hello " → "hello"
✓ "\thello\n" → "hello"
// JavaScript — .trim() exists, but regex is useful for custom trim
str.replace(/^\s+|\s+$/g, '');
// Collapse internal whitespace too
str.replace(/\s+/g, ' ').trim();
# Python
re.sub(r'^\s+|\s+$', '', text)
# Or for internal collapse:
' '.join(text.split())
Tip: For collapsing multiple internal spaces into one, use \s{2,} instead to preserve single spaces.
^(?:4\d{3}|5[1-5]\d{2}|3[47]\d{2}|6(?:011|5\d{2}))[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}$
How it works: The first group identifies the card network: 4\d{3} (Visa), 5[1-5]\d{2} (Mastercard), 3[47]\d{2} (Amex), 6011|65\d{2} (Discover). Remaining groups match four-digit blocks with optional separators.
✓ 4111-1111-1111-1111
✓ 5500 0000 0000 0004
✗ 1234567890123456
✗ 411111111111111 (15 digits)
Security note: Always validate credit cards server-side and run the Luhn algorithm check. Never store raw card numbers — use a payment processor like Stripe or Braintree. This pattern is for format detection only.
^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
How it works: #? makes the hash prefix optional. The alternation [A-Fa-f0-9]{6}|[A-Fa-f0-9]{3} matches either a full 6-character hex value or the shorthand 3-character form.
✓ #FF5733
✓ abc
✓ #09f
✗ #GGGGGG
✗ #12345
// JavaScript — extract colors from CSS
const colors = css.match(/#(?:[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\b/g);
# Python — also match 8-char RGBA hex
re.findall(r'#(?:[A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\b', css_text)
Putting It All Together
Having these patterns in your toolkit eliminates the "let me Google that regex" cycle. Here's a quick-reference object you can drop into any project:
const PATTERNS = {
email: /^[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}$/,
url: /https?:\/\/(?:[\w-]+\.)+[\w-]+(?:\/[\w._~:\/?#\[\]@!$&'()*+,;=%-]*)*/,
ipv4: /^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,
phone: /^(\+?\d{1,3}[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}$/,
date: /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/,
password: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
htmlTag: /<([a-z][a-z0-9]*)\b[^>]*>(.*?)<\/\1>/i,
trim: /^\s+|\s+$/g,
creditCard: /^(?:4\d{3}|5[1-5]\d{2}|3[47]\d{2}|6(?:011|5\d{2}))[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}$/,
hexColor: /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
};
Practice makes permanent. Copy any pattern above and paste it into our
Regex Tester to experiment interactively. Tweak the pattern, feed it edge cases, and build your intuition. You can also format
JSON responses, encode test data with
Base64, or generate test identifiers with the
UUID Generator.
Final Tips for Working with Regex
- Anchor your patterns with
^ and $ when validating — otherwise partial matches sneak through.
- Prefer lazy quantifiers (
*?, +?) over greedy ones when extracting content between delimiters.
- Use non-capturing groups
(?:…) when you need grouping but don't need the captured value — it's slightly faster and keeps match results clean.
- Watch for backtracking — nested quantifiers like
(a+)+ can cause catastrophic performance on long strings.
- Test edge cases — empty strings, maximum lengths, unicode input, and malformed data.
- Know when NOT to regex — JSON, HTML, and XML have proper parsers. Regex is for patterns, not structured data.
Regular expressions are one of the most transferable skills in programming. These 10 patterns work identically across JavaScript, Python, Java, Go, PHP, and virtually every language with a PCRE-compatible engine. Memorize them, understand how each piece works, and you'll spend far less time fighting text processing problems.