iKit
Guide · 10 min read ·

Regex Cheatsheet 2026: 25 Patterns You'll Use Every Week

A practical regex cheatsheet for 2026: 25 ready-to-paste patterns for emails, URLs, dates, and log parsing, plus the syntax rules behind them.

Regex Cheatsheet 2026: 25 Patterns You'll Use Every Week

Regex Cheatsheet: 25 Patterns You'll Use Every Week

Most developers don't write regex from scratch — they recognise a shape they've seen before and adapt it. The problem is remembering the exact syntax under pressure, when a log line won't parse or a form keeps rejecting valid emails. This regex cheatsheet collects the 25 patterns that actually come up week to week, plus the handful of syntax rules that explain why each one works. Every example is JavaScript you can paste straight into a tester.

TL;DR

  • ^...$ anchors a pattern to a whole string; without them you match substrings.
  • \d \w \s match digit, word, and whitespace characters; uppercase negates.
  • Quantifiers are greedy by default — add ? to make them lazy.
  • Named groups (?<name>...) and lookbehind shipped in ES2018 and work everywhere now.
  • Test patterns in a live tester before trusting them in production code.

Regex syntax basics: character classes, quantifiers, and anchors

Before the patterns, three building blocks cover roughly 80% of everything you'll write. Get these solid and the rest of the cheatsheet reads as combinations.

Character classes: \d, \w, \s and their negations

A character class matches one character from a set. The shorthand classes are the ones you'll type constantly, and each has an uppercase negation that matches everything except that set.

Token Matches Negation
\d a digit 0–9 \D
\w letter, digit, or _ \W
\s any whitespace \S
. any char except newline

Per MDN's character-class reference, \w is exactly [A-Za-z0-9_] in the default mode — it does not include accented letters unless you opt into Unicode mode with the u or v flag. That single fact explains a lot of "why won't my pattern match José" bug reports.

You can also build your own class in square brackets: [aeiou] matches one vowel, [a-f] matches one hex letter, and a leading caret negates — [^0-9] matches one non-digit.

Quantifiers: how many times something repeats

A quantifier applies to the token immediately before it. The four you need are * (zero or more), + (one or more), ? (zero or one), and {n,m} (between n and m times).

/\d+/      // one or more digits
/colou?r/  // matches "color" and "colour"
/\d{3,4}/  // three or four digits

According to MDN's quantifiers guide, every quantifier is greedy by default: it matches as much as it can, then gives characters back only if the rest of the pattern fails. Append ? to make it lazy and match as little as possible. This is the single most common source of surprising matches, and it gets its own section below.

Anchors and word boundaries

Anchors match a position, not a character. ^ is the start of the string, $ is the end, and \b is a word boundary — the edge between a \w character and a non-\w character.

/^\d+$/      // the WHOLE string is digits
/\bcat\b/    // the word "cat", not "category"

Forgetting ^...$ is why a "digits only" check passes "12abc" — without anchors, the engine happily finds 12 as a substring and reports success.

The 25 patterns you'll actually use

Here are the workhorses, grouped by what you're trying to do. They're pragmatic, not academic: an email pattern that accepts every RFC 5322 edge case is unreadable and usually worse in practice than a simple one plus a confirmation email.

Validation patterns: email, URL, hex color, password

Wrap each of these in ^...$ so it validates the entire input.

// 1. Integer, optional sign
/^-?\d+$/

// 2. Decimal number
/^-?\d+(?:\.\d+)?$/

// 3. Pragmatic email
/^[^\s@]+@[^\s@]+\.[^\s@]+$/

// 4. http / https URL
/^https?:\/\/[^\s/$.?#].\S*$/i

// 5. Hex color (#fff or #ffffff)
/^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i

// 6. Strong password: 8+, upper, lower, digit
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/

// 7. URL-safe slug
/^[a-z0-9]+(?:-[a-z0-9]+)*$/

// 8. UUID (any version)
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i

Pattern 6 uses lookahead ((?=...)) to assert "contains a lowercase letter" without consuming any characters, then repeats for each requirement. Stack as many lookaheads as you have rules. If you generate IDs, the UUID pattern is handy for input validation — and our UUID generator produces RFC-compliant v4 values you can test it against.

Extraction patterns: dates, IPs, and log timestamps

These aren't anchored — you run them against free text to pull out the parts you want, usually with capture groups.

// 9. ISO date with named groups
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/

// 10. 24-hour time
/\b([01]\d|2[0-3]):[0-5]\d\b/

// 11. IPv4 (loose — see note)
/\b(?:\d{1,3}\.){3}\d{1,3}\b/

// 12. IPv4 (strict 0–255 octets)
/\b(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}
     (?:25[0-5]|2[0-4]\d|1?\d?\d)\b/

// 13. File extension
/\.([a-z0-9]+)$/i

// 14. Markdown link → text + url
/\[([^\]]+)\]\(([^)]+)\)/

// 15. Currency amount
/\$\d{1,3}(?:,\d{3})*(?:\.\d{2})?/

Pattern 11 is the "loose" IPv4 that every tutorial shows — but note it happily matches 999.999.999.999, because \d{1,3} doesn't know that an octet caps at 255. Pattern 12 is the correct version. This trade-off — readable but permissive, versus correct but dense — is the central judgment call in regex work. For log files, these extraction patterns pair naturally with timestamp parsing; see the log section linked at the end.

Cleanup patterns: whitespace, duplicates, and HTML

These are find-and-replace patterns — match the junk, replace with nothing or a single space.

// 16. Collapse runs of whitespace
/\s{2,}/g          // → replace with " "

// 17. Trim trailing whitespace per line
/[ \t]+$/gm

// 18. Leading zeros
/^0+(?=\d)/

// 19. Duplicate word ("the the")
/\b(\w+)\s+\1\b/gi

// 20. Strip simple HTML tags
/<[^>]+>/g

// 21. Trailing comma before ] or }
/,(\s*[}\]])/g

Pattern 19 uses a backreference\1 matches whatever the first group captured, so (\w+)\s+\1 finds a word repeated. Pattern 20's [^>]+ is the key trick: a negated class can't cross the >, so the tag match stops correctly instead of greedily swallowing everything to the last > on the line.

The remaining four round out a full week's toolkit:

  • 22. Phone digits only: /[^\d+]/g to strip formatting before storage.
  • 23. Whole-word search: /\bTODO\b/g to find comment markers.
  • 24. Capture query string: /\?(.+)$/ to grab everything after ?.
  • 25. Blank lines: /^\s*$/gm to find or delete empty lines.

How to test a regex pattern without writing code

You should never trust a regex you haven't run against real data. A live tester shows you exactly what matches, character by character, and surfaces capture groups as you type — far faster than a console.log loop.

Reading the match, groups, and indices

In JavaScript, String.prototype.match (or matchAll for the g flag) returns the full match at index 0 and each capture group after it. Named groups appear under match.groups:

const m = "2026-06-15".match(
  /(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/
);
m.groups.y; // "2026"
m.groups.m; // "06"

A good tester renders these groups visually so you don't have to count brackets. Paste your pattern into the iKit Regex Tester and it highlights every match and group live, entirely in the browser — nothing you paste is uploaded.

Why your regex matches too much: greedy vs lazy

The classic failure is matching across a boundary you meant to respect:

'<b>a</b><b>b</b>'.match(/<b>.*<\/b>/);
// → the WHOLE string, not just <b>a</b>

The greedy .* ate everything to the last </b>. Two fixes: make it lazy with .*?, or — better — use a negated class so the match physically can't overrun:

/<b>.*?<\/b>/   // lazy: stops at first </b>
/<b>[^<]*<\/b>/ // negated: cleaner, faster

The negated-class version is usually the right call because it avoids the backtracking that lazy quantifiers can trigger on large inputs.

Named groups, lookbehind, and the new v flag in 2026

Modern JavaScript regex is far more capable than the version most cheatsheets were written for. Smashing Magazine's history of JavaScript regex traces how the language closed most of the gap with PCRE between ES2018 and ES2024.

How to use named capture groups in JavaScript

Named groups, added in ES2018, replace the brittle "which number was the month?" guessing game. Reference them in replacements with $<name>:

"2026-06-15".replace(
  /(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/,
  "$<d>/$<m>/$<y>"
); // → "15/06/2026"

Lookahead and lookbehind assertions

Lookahead (?=...) and negative lookahead (?!...) have been around for years; lookbehind (?<=...) and (?<!...) arrived in ES2018. Lookbehind lets you match something preceded by a marker without including the marker in the result:

// price digits after a $, without capturing the $
"$42".match(/(?<=\$)\d+/)[0]; // "42"

What the ECMAScript 2024 v flag adds

The newest addition is the v flag (unicodeSets mode), standardised in ECMAScript 2024. Per the V8 team's write-up, it enables set operations inside character classes — intersection [A&&B] and subtraction [A--B] — plus multi-character Unicode properties. Matching every Greek letter except a few becomes a one-liner:

/[\p{Script=Greek}--[αβγ]]/v.test('α'); // false

The V8 article notes v is supported in Chrome 112+, Firefox 116+, Safari 17+, and Node 20+. It can't be combined with the older u flag — pick one.

Common regex mistakes that match too much

Three mistakes account for most "my regex is broken" tickets, and all three trace back to the syntax rules above.

Why .* is almost never what you want

Reaching for .* between two markers is the number-one cause of over-matching, as the <b> example showed. Default to a negated class ([^x]*) and only use .*? when no clean boundary character exists.

Escaping special characters the right way

A literal dot, plus, or question mark must be escaped with a backslash, or it means its regex special. 3.14 as a pattern matches 3x14; you want 3\.14. Inside a character class, most metacharacters lose their power — [.+?] matches a literal dot, plus, or question mark — which is a tidy way to avoid backslash soup.

Forgetting the global flag on replace

String.prototype.replace without the g flag changes only the first match. If a cleanup pattern seems to "only fix one," check for /.../g. When comparing the before-and-after of a bulk replace, our Diff Checker makes the changed lines obvious at a glance.

References

Related on iKit

Related posts