Regex Architect
Overview
Build correct, readable, and safe regular expressions, then prove they work.
Keywords: regex, regular expression, pattern matching, ReDoS, catastrophic
backtracking, validation, extraction, capture group, named group, lookahead,
lookbehind, anchor, Unicode, PCRE, RE2, flavor portability.
This skill exists because regex is easy to write and hard to write well. Naive
patterns silently accept bad input, reject good input, or hang a server when fed
an adversarial string. The job is not just "produce a pattern" — it is to produce
a pattern that is anchored correctly, scoped to the right flavor, free of
exponential backtracking, and accompanied by a test plan.
Use this skill whenever a task involves matching, extracting, replacing, splitting,
or validating text with a pattern — or explaining/debugging an existing one.
Core Principles
- Clarify before constructing. Know the flavor, the input source, whether you
are validating (whole string) or searching (substring), and what counts as
valid. Ambiguity here produces wrong regexes.
- Anchor on purpose. Validation almost always needs
^...$ (or \A...\z).
Search/extract usually must NOT be anchored. Mismatched anchoring is the #1
correctness bug.
- Prefer explicit character classes over
. . is greedy, matches almost
anything, and is a backtracking magnet. Use [^"], [^\n], \d, etc.
- Make quantified subpatterns mutually exclusive. Overlapping alternations or
nested quantifiers (
(a+)+, (a|a)*, (.*)*) cause catastrophic backtracking.
- Readability is a feature. Use named groups, verbose/extended mode, and
comments for anything non-trivial. A regex nobody can edit is a liability.
- Validate with structured logic when regex is the wrong tool. Do not regex
HTML, nested brackets, or full email RFC 5322. Say so and offer a parser.
Workflow
- Gather requirements (see
references/clarifying-questions.md):
- Target flavor / language runtime.
- Validation vs. search vs. replace vs. split.
- Exact set of valid and invalid examples (ask for at least 2 of each).
- Multiline? Unicode? Case sensitivity? Performance constraints / untrusted input?
- Choose a strategy. Pick character classes, anchoring, and grouping. Consult
references/patterns-cookbook.md for vetted building blocks rather than
inventing from scratch.
- Draft the pattern in the requested flavor. Use named capture groups and,
for non-trivial patterns, provide a verbose/commented version too.
- Audit for ReDoS using the checklist in
references/redos-guide.md. Rewrite
nested/overlapping quantifiers; prefer atomic groups, possessive quantifiers,
or bounded {0,n} quantifiers. If the runtime is RE2/Go/Rust, note it is
already linear-time and lookarounds/backrefs are unsupported.
- Explain it. Provide a token-by-token breakdown so the user can maintain it.
- Test it. Run
scripts/regex_test.py with positive and negative cases. It
also runs a lightweight ReDoS timing probe. Report pass/fail per case.
- Note portability. If the user may switch flavors, flag flavor-specific
constructs (lookbehind, named-group syntax,
\d Unicode semantics, inline
flags) per references/flavor-portability.md.
Quick Decision Framework
- "Is this string entirely valid?" → anchor with
^$ (or \A\z); use re.fullmatch
in Python.
- "Find all occurrences." → no anchors; use global/
findall; mind overlapping matches.
- "Untrusted/large input?" → prioritize linear-time design; consider RE2-family
engine; cap input length before matching.
- "Nested or recursive structure (HTML, JSON, code)?" → do NOT use regex; use a parser.
- "Just needs a yes/no on a simple format?" → small anchored class-based pattern.
Worked Example (short)
Validate a US ZIP (5 digits, optional -####), JavaScript:
/^\d{5}(?:-\d{4})?$/
^ / $ anchor the whole string.
\d{5} exactly five digits.
(?:-\d{4})? optional non-capturing group: hyphen + four digits.
Why it is ReDoS-safe: fixed-count quantifiers, no nested/overlapping repetition.
See examples/worked-example.md for a full email-validation walkthrough including
a naive-vs-safe comparison and test output.
Best Practices
- Always provide both the raw pattern and a one-line explanation of anchoring intent.
- Use non-capturing groups
(?:...) unless you need the capture; name the ones you keep.
- For validation, return whole-string semantics explicitly (
fullmatch, \A...\z,
or ^...$ with the right flags).
- Escape user-provided literals; never interpolate raw user input into a pattern.
- Cap input length and/or set engine timeouts when matching untrusted data.
- Offer a verbose/
x-mode version for any pattern longer than ~40 chars.
- Prefer
[0-9] over \d when you must exclude non-ASCII digits (\d matches
Unicode digits in many flavors).
Common Pitfalls
- Unanchored validation —
/\d{5}/ matches inside abc12345xyz. Anchor it.
- Greedy
.* across delimiters — <.*> over <a><b> grabs everything; use
<[^>]*> or lazy <.*?> with care.
- Nested quantifiers —
(\d+)+, (a*)*, (.*,)* → catastrophic backtracking.
- Unescaped dot/metachars in literals —
3.14 matches 3x14; escape to 3\.14.
^/$ with multiline — they match line boundaries under m; use \A/\z
(or \Z) for true string ends.
- Backreferences/lookbehind in RE2/Go/Rust — unsupported; redesign.
- Trying to regex HTML/recursive grammars — wrong tool; use a parser.
\b word-boundary surprises — depends on \w definition and Unicode mode.
Bundled Files
references/patterns-cookbook.md — vetted, safe patterns for common formats with
notes and traps.
references/redos-guide.md — how catastrophic backtracking happens and how to fix it.
references/flavor-portability.md — cross-flavor syntax differences and a mapping table.
references/clarifying-questions.md — the question set to ask before writing a pattern.
scripts/regex_test.py — runnable Python tester for positive/negative cases plus a
ReDoS timing probe.
examples/worked-example.md — end-to-end email-validation example with test output.
1---2name: regex-architect3description: Designs, explains, hardens, and tests regular expressions for parsing and validation tasks (emails, URLs, dates, IPs, log lines, CSV fields, identifiers, etc.) while actively defending against catastrophic backtracking (ReDoS). Use this skill when the user asks to "write a regex", "build/fix a regular expression", "match/extract/validate X with regex", "explain this regex", "why is my regex slow/hanging", check for "ReDoS"/"catastrophic backtracking", or convert a pattern between flavors (PCRE, Python re, JavaScript, Java, Go RE2, .NET). Covers capturing/named groups, anchors, lookarounds, Unicode, and flavor portability.4license: MIT5---67# Regex Architect89## Overview10Build correct, readable, and *safe* regular expressions, then prove they work.11Keywords: regex, regular expression, pattern matching, ReDoS, catastrophic12backtracking, validation, extraction, capture group, named group, lookahead,13lookbehind, anchor, Unicode, PCRE, RE2, flavor portability.1415This skill exists because regex is easy to write and hard to write *well*. Naive16patterns silently accept bad input, reject good input, or hang a server when fed17an adversarial string. The job is not just "produce a pattern" — it is to produce18a pattern that is anchored correctly, scoped to the right flavor, free of19exponential backtracking, and accompanied by a test plan.2021Use this skill whenever a task involves matching, extracting, replacing, splitting,22or validating text with a pattern — or explaining/debugging an existing one.2324## Core Principles251. **Clarify before constructing.** Know the flavor, the input source, whether you26 are validating (whole string) or searching (substring), and what counts as27 valid. Ambiguity here produces wrong regexes.282. **Anchor on purpose.** Validation almost always needs `^...$` (or `\A...\z`).29 Search/extract usually must NOT be anchored. Mismatched anchoring is the #130 correctness bug.313. **Prefer explicit character classes over `.`** `.` is greedy, matches almost32 anything, and is a backtracking magnet. Use `[^"]`, `[^\n]`, `\d`, etc.334. **Make quantified subpatterns mutually exclusive.** Overlapping alternations or34 nested quantifiers (`(a+)+`, `(a|a)*`, `(.*)*`) cause catastrophic backtracking.355. **Readability is a feature.** Use named groups, verbose/extended mode, and36 comments for anything non-trivial. A regex nobody can edit is a liability.376. **Validate with structured logic when regex is the wrong tool.** Do not regex38 HTML, nested brackets, or full email RFC 5322. Say so and offer a parser.3940## Workflow411. **Gather requirements** (see `references/clarifying-questions.md`):42 - Target flavor / language runtime.43 - Validation vs. search vs. replace vs. split.44 - Exact set of valid and invalid examples (ask for at least 2 of each).45 - Multiline? Unicode? Case sensitivity? Performance constraints / untrusted input?462. **Choose a strategy.** Pick character classes, anchoring, and grouping. Consult47 `references/patterns-cookbook.md` for vetted building blocks rather than48 inventing from scratch.493. **Draft the pattern** in the requested flavor. Use named capture groups and,50 for non-trivial patterns, provide a verbose/commented version too.514. **Audit for ReDoS** using the checklist in `references/redos-guide.md`. Rewrite52 nested/overlapping quantifiers; prefer atomic groups, possessive quantifiers,53 or bounded `{0,n}` quantifiers. If the runtime is RE2/Go/Rust, note it is54 already linear-time and lookarounds/backrefs are unsupported.555. **Explain it.** Provide a token-by-token breakdown so the user can maintain it.566. **Test it.** Run `scripts/regex_test.py` with positive and negative cases. It57 also runs a lightweight ReDoS timing probe. Report pass/fail per case.587. **Note portability.** If the user may switch flavors, flag flavor-specific59 constructs (lookbehind, named-group syntax, `\d` Unicode semantics, inline60 flags) per `references/flavor-portability.md`.6162## Quick Decision Framework63- **"Is this string entirely valid?"** → anchor with `^$` (or `\A\z`); use `re.fullmatch`64 in Python.65- **"Find all occurrences."** → no anchors; use global/`findall`; mind overlapping matches.66- **"Untrusted/large input?"** → prioritize linear-time design; consider RE2-family67 engine; cap input length before matching.68- **"Nested or recursive structure (HTML, JSON, code)?"** → do NOT use regex; use a parser.69- **"Just needs a yes/no on a simple format?"** → small anchored class-based pattern.7071## Worked Example (short)72Validate a US ZIP (5 digits, optional `-####`), JavaScript:73```js74/^\d{5}(?:-\d{4})?$/75```76- `^` / `$` anchor the whole string.77- `\d{5}` exactly five digits.78- `(?:-\d{4})?` optional non-capturing group: hyphen + four digits.7980Why it is ReDoS-safe: fixed-count quantifiers, no nested/overlapping repetition.81See `examples/worked-example.md` for a full email-validation walkthrough including82a naive-vs-safe comparison and test output.8384## Best Practices85- Always provide both the raw pattern and a one-line explanation of anchoring intent.86- Use non-capturing groups `(?:...)` unless you need the capture; name the ones you keep.87- For validation, return whole-string semantics explicitly (`fullmatch`, `\A...\z`,88 or `^...$` with the right flags).89- Escape user-provided literals; never interpolate raw user input into a pattern.90- Cap input length and/or set engine timeouts when matching untrusted data.91- Offer a verbose/`x`-mode version for any pattern longer than ~40 chars.92- Prefer `[0-9]` over `\d` when you must exclude non-ASCII digits (`\d` matches93 Unicode digits in many flavors).9495## Common Pitfalls96- **Unanchored validation** — `/\d{5}/` matches inside `abc12345xyz`. Anchor it.97- **Greedy `.*` across delimiters** — `<.*>` over `<a><b>` grabs everything; use98 `<[^>]*>` or lazy `<.*?>` with care.99- **Nested quantifiers** — `(\d+)+`, `(a*)*`, `(.*,)*` → catastrophic backtracking.100- **Unescaped dot/metachars in literals** — `3.14` matches `3x14`; escape to `3\.14`.101- **`^`/`$` with multiline** — they match line boundaries under `m`; use `\A`/`\z`102 (or `\Z`) for true string ends.103- **Backreferences/lookbehind in RE2/Go/Rust** — unsupported; redesign.104- **Trying to regex HTML/recursive grammars** — wrong tool; use a parser.105- **`\b` word-boundary surprises** — depends on `\w` definition and Unicode mode.106107## Bundled Files108- `references/patterns-cookbook.md` — vetted, safe patterns for common formats with109 notes and traps.110- `references/redos-guide.md` — how catastrophic backtracking happens and how to fix it.111- `references/flavor-portability.md` — cross-flavor syntax differences and a mapping table.112- `references/clarifying-questions.md` — the question set to ask before writing a pattern.113- `scripts/regex_test.py` — runnable Python tester for positive/negative cases plus a114 ReDoS timing probe.115- `examples/worked-example.md` — end-to-end email-validation example with test output.