Skip to content
JavaScript3 min read

Regex Patterns Cheatsheet: 25 Copy-Paste Examples

Battle-tested regex cheatsheet with 25 copy-paste patterns for email, URLs, dates, plus flags, groups, and catastrophic backtracking fixes.

By IvyIvy TeamPublished Updated
#regex#javascript#validation#patterns

Quick Syntax Table

TokenMeaningExample
.Any char except newlinea.c matches abc
\d / \DDigit / non-digit\d{3}-\d{4}
\w / \sWord char / whitespace\w+@\w+
^ / $Start / end anchors^\d+$
* + ? {n,m}Quantifiers\d{4}-\d{2}
[abc] [^abc]Class / negated class[^@\s]+
( ) (?: )Capture / non-capture(\d+)-(\d+)
|Alternationcat|dog
(?<name>)Named group(?<year>\d{4})

Flags You Actually Need

const re = /hello/gi; // g = global, i = case-insensitive
/^start/m.test("a\nstart"); // m = ^$ match per line
/\p{Letter}+/u.test("café"); // u = unicode-aware
const ssn = /\d{3}-\d{2}-\d{4}/y; // y = sticky (match at lastIndex)

25 Copy-Paste Patterns

const P = {
  email: /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/,
  url: /^https?:\/\/[^\s/$.?#].[^\s]*$/i,
  slug: /^[a-z0-9]+(?:-[a-z0-9]+)*$/,
  ipv4: /^(?:25[0-5]|2[0-4]\d|1?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|1?\d?\d)){3}$/,
  hexColor: /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i,
  dateISO: /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/,
  time24: /^([01]\d|2[0-3]):[0-5]\d$/,
  phoneIntl: /^\+?[1-9]\d{6,14}$/,
  username: /^[a-zA-Z0-9_]{3,16}$/,
  passwordStrong: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,}$/,
  zipUS: /^\d{5}(?:-\d{4})?$/,
  creditCard: /^(?:\d[ -]*?){13,19}$/, // validate with Luhn separately
  uuid: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
  base64: /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,
  htmlTag: /<([a-z][\w-]*)(?:\s[^<>]*)?>/i,
  hashtag: /#[A-Za-z0-9_]{2,}/g,
  whitespaceTrim: /^\s+|\s+$/g,
};

Real-World Validation (JS)

function isEmail(v) {
  return typeof v === "string" && v.length <= 254 && P.email.test(v.trim());
}

// Extract with named groups
const m = "2026-10-09".match(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/);
console.log(m?.groups); // { y: '2026', m: '10', d: '09' }

// Mask a card number, keep last 4
const masked = "4111 1111 1111 1111".replace(/\d(?=\d{4})/g, "•");

Lookahead / Lookbehind

// Password: 8+ chars with upper, lower, digit
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/.test("IvyRocks42"); // true

// Match "invoice" NOT followed by "draft"
/invoice(?!\s*draft)/i.test("Invoice 1042"); // true

// Price preceded by $
/(?<=\$)\d+(?:\.\d{2})?/.exec("Total: $49.99"); // 49.99

Edge case: lookbehind ((?<=...)) works in all modern browsers and Node 18+, but not in older Safari (<16.4). Provide a fallback capture group for legacy clients.

Catastrophic Backtracking

Nested quantifiers like (a+)+$ can hang on long inputs — a ReDoS vector.

// DANGEROUS — exponential on "aaaaaaaaaaaaaaaa!"
/^(a+)+$/.test("a".repeat(30) + "!");

Fixes:

  1. Use atomic-style restraint: /^a+$/ instead of /^(a+)+$/.
  2. Prefer possessive equivalents or limit length first: if (s.length > 1000) reject();.
  3. For user-supplied patterns, run server-side with a timeout library.

Testing Tips

  • Always anchor validation patterns with ^...$, or test('xx@yy') passes inside junk.
  • Test the reject cases: empty string, 10k chars, unicode, newlines.
  • Try your pattern live in tools.ivyivy.com regex tester before shipping, and keep a unit test per pattern.