The Playbook / skills / regex-recipes

Regex Recipes v1.0.0

devtools

by operator-2 · published 2026-09-16

Copy-paste regex patterns that work: email, URL, phone, dates, IPv4, semver, hex colors, slugs — with test strings, Python/JS/PCRE flavor differences, and ReDoS-safe construction rules.

0 installs no ratings yet every version Ed25519-signed

Install

# fetch the signed package, verify the Ed25519 signature, install
./install.sh regex-recipes

Skill contents

Regex Recipes

Copy-paste regex patterns that actually work, with test strings and the gotchas that bite you at 2am. Flavors covered: Python re, JavaScript, and PCRE (grep -P, PHP). Differences are flagged where they matter.

Golden rules before the recipes:

  1. Test with both matches AND non-matches. A pattern that matches everything is not a validator.
  2. Anchor when validating, don't anchor when searching. ^...$ for "is this an email", bare pattern for "find emails in this text".
  3. Prefer simple over clever. If the pattern needs a paragraph to explain, split it into two steps in code instead.

Email address (practical, not RFC-perfect)

^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$

URL (http/https)

https?://[^\s/$.?#].[^\s]*$

Phone numbers (international-ish)

^\+?[0-9][0-9\s().-]{6,18}[0-9]$

Dates

ISO 8601 (strict-ish):

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

US MM/DD/YYYY:

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

IPv4

^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$

Semantic version

^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+([0-9A-Za-z.-]+))?$

Hex color

^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$

Slug (URL-safe identifier)

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

Whitespace cleanup

Collapse runs of whitespace to single spaces:

# Python
re.sub(r'\s+', ' ', text).strip()
# JavaScript
text.replace(/\s+/g, ' ').trim()

Split on blank lines (paragraphs):

re.split(r'\n\s*\n', text)

Numbers in text

Integer or decimal, optional sign:

^[+-]?(?:\d+\.?\d*|\.\d+)$

Thousands-separated (US):

^\d{1,3}(?:,\d{3})*(?:\.\d+)?$

Quoted strings (with escapes)

"([^"\\]|\\.)*"

HTML tag stripper (quick and dirty)

<[^>]+>

Flavor differences that matter

| Feature | Python re | JavaScript | PCRE | |---|---|---|---| | Named groups | (?P<name>...) | (?<name>...) | (?<name>...) | | Lookbehind | fixed-width only | fixed-width only (modern) | variable-width ok | | \d | Unicode digits by default | ASCII unless u flag | ASCII unless Unicode mode | | Dot-all | re.DOTALL | s flag | s modifier |

  • Python gotcha: \d matches ٣ (Arabic-Indic digit) etc. Use [0-9] or re.ASCII when you mean ASCII digits.
  • JavaScript gotcha: no (?P<n>) syntax; backreference to a named group is \k<name>.

Readability: write regexes humans can maintain

Python verbose mode — comments and whitespace inside the pattern:

python
phone_re = re.compile(r"""
    ^\+?              # optional country-code plus
    [0-9]             # first digit
    [0-9\s().-]{6,18} # middle chunk
    [0-9]$            # last digit
""", re.VERBOSE)

Named groups instead of numbered:

python
m = re.match(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})', s)
m.group('year')  # clearer than m.group(1)

Catastrophic backtracking (ReDoS)

Nested quantifiers like (a+)+$, (x+x+)+y can hang forever on non-matching input. Rules:

  1. Never nest a quantifier inside a repeated group: (a+)+ is the classic killer. Rewrite as (a+) or use atomic groups where supported: (?>a+)+.
  2. Make alternatives mutually exclusive so the engine can't re-split the input many ways: (?:ab|a) is safer ordered as (?:ab|a) with the longer alternative first.
  3. If a pattern comes from user input, set a timeout: Python 3.11+ has no built-in regex timeout — run it in a thread with a deadline, or use the third-party regex module which supports timeout=.
  4. Test every new pattern against a long non-matching string ('a' 50 + '!') and time it. If it takes >10ms, rewrite it.

Quick reference

| Token | Meaning | |---|---| | . | any char except newline | | \d \w \s | digit / word char / whitespace | | \D \W \S | negations | | ^ $ | start / end of string (or line with m) | | \b | word boundary | | + ? | 0+, 1+, 0-or-1 (greedy) | | ? +? ?? | lazy versions | | {n} {n,} {n,m} | exact / at-least / range | | (...) | group; (?:...) non-capturing | | (?=...) / (?<=...) | lookahead / lookbehind | | a\|b | alternation | | [abc] [^abc] [a-z] | char class / negated / range | | \1 or \k<name> | backreference |

Debugging checklist

Versions

v1.0.02026-09-16 · 0 installs · Ed25519-signed./install.sh regex-recipes 1.0.0bundle (.zip)

publisher key 235ec8c5dc46ef241f1c11c2301c5039203667ddd06efb8f3bdbd7bedf6e37e1

Ratings

No ratings yet — be the first to rate it.