← Back to Blog
·12 min read

The 20 Regex Patterns Every Developer Needs (With Explanations)

The problem with regex cheat sheets is they give you the pattern without explaining why it works, so you can't adapt it when requirements change. Here are 20 essential patterns with full breakdowns — and strong opinions on the email debate.

Email — the settled debate

The "validate email with regex" debate is settled. The RFC 5322 regex is 6,400 characters long, still misses some valid edge cases, and is unmaintainable. The actually correct answer: use a liberal pattern to catch obvious typos, then verify by sending an email.

// Liberal email pattern — use this:
const email = /^[^s@]+@[^s@]+.[^s@]+$/;

// Breakdown:
// ^         — start of string
// [^s@]+   — one or more chars that aren't whitespace or @
// @         — literal @
// [^s@]+   — one or more chars for domain
// .        — literal dot
// [^s@]+   — TLD (at least one char)
// $         — end of string

// Catches: missing @, missing TLD, spaces
// Accepts: "user@company.co.uk", "a+b@c.io"
// Does NOT validate: whether the domain exists, complex subaddressing

URL, UUID, and IP Address

// URL — catches http and https, with or without path/query:
const url = /^https?://[^s/$.?#].[^s]*$/i;
// https? — optional s for https
// :// — literal "://"
// [^s/$.?#]. — first domain char (not whitespace or special)
// [^s]* — rest of URL (anything not whitespace)

// UUID v4:
const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
// The "4" in position 13 and [89ab] in position 17 are UUID v4-specific.
// Use /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
// for any UUID version.

// IPv4 address:
const ipv4 = /^(?:(?:25[0-5]|2[0-4]d|[01]?dd?).){3}(?:25[0-5]|2[0-4]d|[01]?dd?)$/;
// 25[0-5] — 250-255
// 2[0-4]d — 200-249
// [01]?dd? — 0-199 (with optional leading zeros)
// .){3} — first three octets end with .
// Last octet follows without trailing dot

Dates, timestamps, and semantic versions

// ISO 8601 date (YYYY-MM-DD):
const isoDate = /^d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])$/;
// (0[1-9]|1[0-2]) — months 01-12
// (0[1-9]|[12]d|3[01]) — days 01-31
// Note: doesn't validate that Feb 31 is invalid — that needs code logic.

// ISO 8601 datetime with timezone:
const isoDatetime = /^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}(.d+)?(Z|[+-]d{2}:d{2})$/;

// Semantic version (semver):
const 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 regex.
// (0|[1-9]d*) — no leading zeros in version numbers
// (?:-(prerelease))? — optional pre-release identifier
// (?:+(build))?  — optional build metadata

Hex colors, slugs, and passwords

// Hex color (#fff or #ffffff):
const hexColor = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
// Matches shorthand (#rgb) and full (#rrggbb).
// Add |[0-9a-f]{8} for 8-digit hex (with alpha).

// URL slug (lowercase letters, numbers, hyphens):
const slug = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
// No leading/trailing hyphens, no consecutive hyphens.

// Password strength: min 8 chars, requires uppercase, lowercase, digit, special char:
const strongPassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[^a-zA-Z0-9s]).{8,}$/;
// Four lookaheads assert presence of each character class.
// .{8,} is the actual match — at least 8 of anything.
// The lookaheads don't restrict position, just presence.

// Credit card (major networks, with or without spaces/dashes):
const creditCard = /^(?:4d{12}(?:d{3})?|5[1-5]d{14}|3[47]d{13}|6011d{12})$/;
// 4... — Visa (13 or 16 digits)
// 5[1-5]... — Mastercard (16 digits)
// 3[47]... — Amex (15 digits)
// 6011... — Discover (16 digits)
// Always run Luhn algorithm check in addition to regex.

Code patterns: imports, Git hashes, and file extensions

// JavaScript/TypeScript import statement:
const importStmt = /^imports+(?:(?:[w*{}

	, ]+)s+froms+)?['"]([^'"]+)['"]/m;
// Captures the module path (group 1).
// Handles: import x from 'y', import { a, b } from 'y', import * as x from 'y'

// Git commit hash (short 7-char or full 40-char SHA1):
const gitHash = /^[0-9a-f]{7,40}$/i;

// File extension extraction:
const fileExt = /.([^./\]+)$/;
// Matches the last dot-separated segment at the end of a path.
// "archive.tar.gz".match(fileExt)?.[1] === "gz"

// JWT token (three base64url segments separated by dots):
const jwt = /^[A-Za-z0-9_-]+.[A-Za-z0-9_-]+.[A-Za-z0-9_-]+$/;
// Note: this validates the format only — not the signature.
// Always verify JWT signatures server-side with a proper library.

// Markdown link: [text](url)
const markdownLink = /[([^]]+)](([^)]+))/g;
// Group 1: link text, Group 2: URL

HTML tag detection and SQL injection patterns

// Detect any HTML tag (for sanitization detection — not parsing):
const htmlTag = /<[^>]+>/g;
// Warning: never parse HTML with regex.
// Use this only to detect the presence of tags, not to process them.

// SQL injection detection (common patterns):
const sqlInjection = /(?:'|--|;|/*|*/|xp_|execs|unions+select|drops+table)/i;
// This is a heuristic detector, not a security guarantee.
// Always use parameterized queries / prepared statements.
// Regex-based SQL injection detection is defense-in-depth, not primary defense.

// Phone number (international format, flexible):
const phone = /^+?[ds-().]{7,15}$/;
// ^+? — optional leading +
// [ds-().]+ — digits, spaces, hyphens, parens, dots
// {7,15} — minimum 7 digits (local), max 15 (international standard E.164)
// Better approach: use libphonenumber-js for validation.

The right way to use these patterns

Every pattern above has known edge cases and limitations. The correct approach to using regex patterns in production:

  1. Understand what the pattern matches and what it doesn't. Read the breakdown.
  2. Add unit tests with your specific edge cases before shipping.
  3. For security-critical validation (email verification, credit cards), combine regex format checking with backend semantic validation (send the email, run Luhn check).
  4. Document the limitations inline. Future maintainers will thank you.
  5. Consider library alternatives for complex formats: libphonenumber-js for phones, validator.js for many common formats.

A regex pattern is not a specification — it's an approximation. Know what approximation you're making, and make sure it's the right one for your use case.

Published May 19, 2026 · By the utili.dev Team