</>CodeScrub

10 Regex Patterns Every Developer Should Know

A practical cheat sheet of 10 regex patterns you'll use again and again — email, URL, phone, IP address, dates, passwords, and more. Copy-paste ready with explanations.

9 min read
  • regex
  • reference
  • patterns
  • cheat-sheet

title: "10 Regex Patterns Every Developer Should Know" description: "A practical cheat sheet of 10 regex patterns you'll use again and again — email, URL, phone, IP address, dates, passwords, and more. Copy-paste ready with explanations." date: "2026-06-05" tags: ["regex", "reference", "patterns", "cheat-sheet"] relatedTool: "regex-tester" published: true

These are the regex patterns that come up in every codebase. Each one includes the pattern, what it matches, known limitations, and a test string you can paste into any regex tester to verify it against your data. Bookmark this page — you'll be back.

1. Email Address

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

Matches: standard email addresses with a local part, @, domain, and TLD of two or more letters.

Example matches: user@example.com, first.last@company.co.uk, user+tag@gmail.com.

Non-matches: @domain.com, user@, user@.com.

Limitations: doesn't verify the domain exists or that the address is deliverable. It rejects some technically valid but exotic RFC 5322 forms (quoted local parts, IP-address domains) that almost no real user ever types. The intentional trade-off here is that Gmail's + addressing works, multi-part TLDs like .co.uk work, and truly broken input gets caught — at the cost of accepting .museum and rejecting alice@[192.168.1.1]. Ship regex as a first-pass filter; use a verification email for actual proof of ownership.

Test string:

user@example.com bad@ also+valid@test.co.uk missing@tld @nope.com plain.text

2. URL (HTTP / HTTPS)

https?:\/\/[^\s<>"{}|\\^`\[\]]+

Matches: HTTP and HTTPS URLs, including query strings and fragments.

Example matches: https://example.com, http://api.test.io/v2/users?id=42, https://site.com/path#anchor.

Non-matches: ftp://files.com, just-text, www.no-protocol.com.

Limitations: doesn't validate whether the URL actually resolves. Accepts technically malformed paths (double slashes, unencoded characters) that a real HTTP client might reject. It also won't match protocol-relative URLs (//cdn.example.com/lib.js) — those are common in CSS/HTML but usually not what you want to extract from prose. When you need the pieces (host, port, path, query, hash), don't parse them out of this match yourself; feed the matched string into new URL(...) or your language's equivalent and let it do the structural work.

Test string:

Visit https://example.com or http://api.test.io/v2?id=42 but not ftp://nope.com or bare words

3. Phone Number (North American)

\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}

Matches: US and Canadian phone numbers in the most common written formats.

Example matches: (555) 123-4567, 555.987.6543, 555-000-1111, 5551234567.

Non-matches: 12345, 555-12-3456, +44 20 7946 0958.

Limitations: doesn't validate the area code (some are unassigned, some are toll-free like 800/888, some are fictional like 555 used only in film and TV) and only handles North American formats. For anything global, use Google's libphonenumber port — the international rules involve country codes, variable-length national numbers, extensions, and hundreds of local exceptions that regex fundamentally cannot express. If you only need a rough shape check for a signup form, this pattern is fine; if the number will be used to actually dial or SMS, use the library.

Test string:

Call (555) 123-4567 or 555.987.6543 or 5551234567 but not 12345

4. IPv4 Address

\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

Matches: valid IPv4 addresses with each octet in the 0–255 range.

Example matches: 192.168.1.1, 10.0.0.255, 8.8.8.8.

Non-matches: 256.1.1.1, 192.168.1, 1.2.3.4.5.

Limitations: doesn't distinguish routable from reserved addresses (private ranges like 10.0.0.0/8, loopback 127.0.0.0/8, multicast, link-local). If your app needs to reject internal addresses (an SSRF check, for instance), do that with a dedicated CIDR-check function after the regex succeeds. It also doesn't handle IPv6 — that's a fundamentally different pattern with eight colon-separated hextets, optional :: compression, and IPv4-mapped edge cases; use a library rather than a regex.

Test string:

Server at 192.168.1.1 and 8.8.8.8 but not 999.999.999.999 or 1.2.3

5. Date (YYYY-MM-DD / ISO 8601)

\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])

Matches: dates in ISO 8601 YYYY-MM-DD format with valid month (01–12) and day (01–31) ranges.

Example matches: 2026-05-28, 2024-01-01, 2025-12-31.

Non-matches: 2026-13-01, 2026-00-15, 28-05-2026.

Limitations: validates format, not calendar reality. It will happily accept 2026-02-31 (February 31st doesn't exist) and doesn't check for leap years, so 2025-02-29 slips through even though 2025 is not a leap year. Regex should be a shape check only for dates; parse the matched string with your language's date library (Date.parse, datetime.fromisoformat, time.Parse) and treat a parsing failure as the real validity signal. That two-step is more reliable than any regex complex enough to encode the calendar itself.

Test string:

Created 2026-05-28, updated 2024-01-01, invalid 2026-13-45 and 99-01-01

6. Hex Color Code

#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b

Matches: three-digit and six-digit hex color codes with a leading #.

Example matches: #fff, #3498db, #E74C3C.

Non-matches: #gg0000 (non-hex letters), 3498db (no hash), #12345 (five digits — neither a valid short nor long form).

Limitations: doesn't match eight-digit hex with an alpha channel (#3498dbff) — extend the alternation with [0-9a-fA-F]{8} if you're accepting alpha too. It also doesn't recognize CSS named colors (red, cornflowerblue), rgb() / hsl() / oklch() functions, or CSS custom properties. If your source is real CSS, use a proper CSS parser; regex will always be one syntax evolution behind.

Test string:

Colors: #3498db and #fff and #E74C3C but not #xyz or 3498db or #12345

7. Strong Password Validator

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*(),.?":{}|<>])[A-Za-z\d!@#$%^&*(),.?":{}|<>]{8,}$

Matches: strings of at least eight characters containing at least one lowercase letter, one uppercase letter, one digit, and one special character.

Example matches: P@ssw0rd!, MyStr0ng#Pass.

Non-matches: password (no uppercase, no digit, no symbol), PASSWORD1 (no lowercase, no symbol), Pass1234 (no symbol).

Limitations: regex-based password validation is genuinely debatable. Length matters more than character-class complexity — NIST 800-63B now recommends a 12+ character minimum and dropping composition rules entirely, because P@ssw0rd! is trivial to crack and correcthorsebatterystaple is not. Use this pattern as a floor, not a signal of strength, and pair it with a check against a breached-password database.

Test string:

P@ssw0rd! weak password123 NoSpecial1 Sh0rt! GoodP@ss99

8. HTML Tag

<\/?([a-zA-Z][a-zA-Z0-9]*)\b[^>]*>

Matches: individual HTML opening and closing tags, including tags with attributes and self-closing tags.

Example matches: <div>, <p class="text">, </span>, <img src="a.jpg" />.

Non-matches: < div> (leading space), <123> (numeric tag name), plain text.

Limitations: this pattern is fine for extracting or identifying individual tags — pulling every <img> out of a snippet, listing which tag names appear in a document, that kind of thing. It is emphatically not for parsing a full HTML document — nested elements, malformed markup, comment blocks, <script> and <style> contents, and text-vs-tag disambiguation all require a real HTML parser. Reach for DOMParser in the browser, cheerio or node-html-parser in Node, BeautifulSoup in Python, or goquery in Go. Anyone who tells you they've written a regex that parses HTML has a subtle bug in production they haven't noticed yet.

Test string:

<div class="box"><p>Hello</p><br/><img src="cat.jpg"></div>

9. Whitespace Trimmer

^\s+|\s+$

Use with the gm (global + multiline) flags so it hits every line, not just the whole string.

Matches: leading and trailing whitespace at the start and end of each line.

Use case: cleaning up pasted user input, trimming log lines before parsing, normalizing indented text.

Non-matches: whitespace between words (as it should be).

Limitations: doesn't collapse multiple internal spaces into one. If you also want that, add a separate pass with \s{2,} replaced by a single space, or use your language's dedicated trim and normalize functions instead of regex. Note that \s differs subtly between engines — JavaScript's \s matches Unicode whitespace by default, while Go's regexp \s only matches ASCII whitespace unless you specify the Unicode flag. If your input can contain non-breaking spaces ( , common in copy-pasted content) or zero-width joiners, verify your engine's \s covers them or add the specific characters explicitly.

Test string (note the deliberate leading and trailing spaces):

  leading  
  both sides  
 trailing   

10. Slug / URL-Safe String Validator

^[a-z0-9]+(?:-[a-z0-9]+)*$

Matches: lowercase URL slugs made of alphanumeric groups joined by single hyphens.

Example matches: hello-world, my-blog-post, regex-101.

Non-matches: Hello-World (uppercase), my--post (double hyphen), -leading-hyphen, trailing-hyphen-.

Limitations: doesn't enforce a maximum length (add {1,64} bounds if you care) and doesn't allow underscores. If your slug format permits underscores, add _ to both character classes: ^[a-z0-9_]+(?:-[a-z0-9_]+)*$. It also doesn't reject reserved words that would break routing (new, edit, admin), so if slugs collide with your app's URL structure, maintain a small blocklist checked after the regex. And if you accept non-ASCII slugs — Japanese, Cyrillic, emoji — this pattern rejects all of them; use the Unicode-aware \p{L} class with the u flag in JavaScript, or the equivalent in your language.

Test string:

hello-world valid-slug my--bad -nope nope- UPPER-case also_underscores

Test These Patterns

Paste any pattern above into the CodeScrub Regex Tester to see matches highlighted in real time against a test string of your own. The token-by-token explainer breaks every part of the pattern into plain English, so you understand why a match succeeds or fails — not just whether it does. That's the difference between copying a regex and knowing what it will do to tomorrow's data.

When Regex Isn't the Answer

Regex is powerful for pattern matching but genuinely terrible for parsing structured formats. Don't use it to parse HTML, JSON, XML, or CSV — the grammars are recursive and context-sensitive, and every attempt to shoehorn regex into them ends in a subtly broken production bug. Use a real parser. Don't rely on regex alone for email validation either — pair it with a verification email if the address's existence actually matters to your product. And don't lean on regex for password strength; check length, check against a breached-password list (haveibeenpwned has a free API), and stop making users invent P@ssw0rd!.

One more thing to avoid: never trust user-supplied regex. Passing an unbounded pattern to your engine invites ReDoS (regular expression denial of service) — a pattern like (a+)+b on an input of many as takes exponentially long to fail. If your product lets users provide their own patterns, run them in a sandbox with a hard timeout, or reach for an engine like Google's RE2 that guarantees linear time by refusing backreferences and lookarounds in the first place.

Bookmark this page

Bookmark this cheat sheet. When you need a pattern, grab it, paste it into the CodeScrub Regex Tester to verify it against your specific data, and ship with confidence.

Ad space · blog-article-mid