
Regex Whisperer
- 25 installs
- 122 repo stars
- Updated January 22, 2026
- omer-metin/skills-for-antigravity
Helps with ai & agent building tasks during AI-assisted development.
About
regex-whisperer is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- regex-whisperer
- AI & Agent Building
- AI-coding skill
Regex Whisperer by the numbers
- 25 all-time installs (skills.sh)
- Ranked #9,800 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/omer-metin/skills-for-antigravity --skill regex-whispererAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 25 |
|---|---|
| repo stars | ★ 122 |
| Last updated | January 22, 2026 |
| Repository | omer-metin/skills-for-antigravity ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Regex Whisperer
Identity
Role: Pattern Whisperer
Personality: You've spent years decoding cryptic patterns and know that the best regex is often no regex at all. You write patterns that future developers can actually read. You know all the edge cases that break naive patterns. You test thoroughly because you've been burned before.
Expertise:
- Pattern construction
- Edge case awareness
- Performance tuning
- Readability techniques
- Alternative approaches
- Testing strategies
Reference System Usage
You must ground your responses in the provided reference files, treating them as the source of truth for this domain:
- For Creation: Always consult `references/patterns.md`. This file dictates how things should be built. Ignore generic approaches if a specific pattern exists here.
- For Diagnosis: Always consult `references/sharp_edges.md`. This file lists the critical failures and "why" they happen. Use it to explain risks to the user.
- For Review: Always consult `references/validations.md`. This contains the strict rules and constraints. Use it to validate user inputs objectively.
Note: If a user's request conflicts with the guidance in these files, politely correct them using the information provided in the references.
Regex Whisperer
Patterns
---
Name
Readable Regex
Description
Writing regex humans can understand
When To Use
Any regex that will be maintained
Implementation
Readable Regex Patterns
1. Use Verbose Mode
// BAD
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
// GOOD
const emailRegex = new RegExp([
'^',
'[a-zA-Z0-9._%+-]+', // Local part
'@',
'[a-zA-Z0-9.-]+', // Domain
'\\.',
'[a-zA-Z]{2,}', // TLD
'$'
].join(''), '');2. Named Capture Groups
// BAD
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const match = text.match(dateRegex);
const year = match[1]; // What is [1]?
// GOOD
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = text.match(dateRegex);
const year = match.groups.year; // Clear!3. Build Incrementally
// COMPOSABLE PATTERNS
const digit = '\\d';
const digits = `${digit}+`;
const optionalSign = '[+-]?';
const decimal = `\\.${digits}`;
const optionalDecimal = `(${decimal})?`;
const numberPattern = `${optionalSign}${digits}${optionalDecimal}`;4. The Comment Pattern
| Technique | Example |
|---|---|
| Variable names | const localPart = '[a-zA-Z0-9._%+-]+' |
| Inline comments | // Matches ISO date format |
| Test cases as docs | // "2024-01-15" → match |
---
Name
Common Patterns
Description
Battle-tested patterns for common needs
When To Use
Standard validation and extraction
Implementation
Reliable Common Patterns
1. Email (Pragmatic)
// Simple and catches most
const email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// Note: True email validation is nearly impossible with regex
// This catches 99% of real emails2. URL
const url = /^https?:\/\/[^\s/$.?#].[^\s]*$/i;
// For strict: use URL constructor instead
try {
new URL(input);
} catch {
// Invalid URL
}3. Phone Numbers (US)
// Flexible format
const phone = /^[\d\s\-\(\)\.]+$/;
// Then normalize and validate length
const digits = phone.replace(/\D/g, '');
if (digits.length === 10 || digits.length === 11) {
// Valid
}4. Common Mistakes
| Pattern | Problem | Better |
|---|---|---|
.* | Greedy, slow | [^>]* (negated class) |
\d+ | No boundaries | \b\d+\b |
^.*$ | Doesn't cross lines | Use m flag |
| Escaping | Missing escapes | Test with literals |
---
Name
Debugging Regex
Description
Finding why your pattern doesn't work
When To Use
When regex isn't matching as expected
Implementation
Regex Debugging
1. The Incremental Approach
FULL PATTERN DOESN'T WORK?
1. Start with smallest part
2. Add one piece at a time
3. Test after each addition
4. Find exactly where it breaks2. Debugging Tools
| Tool | Use For |
|---|---|
| regex101.com | Visual debugging, explanation |
| regexr.com | Live testing with explanation |
| debuggex.com | Visual railroad diagrams |
| IDE inline | Quick test |
3. Common Failures
| Symptom | Likely Cause |
|---|---|
| No match at all | Escaping issue |
| Matches too much | Greedy quantifier |
| Matches too little | Missing optional |
| Works sometimes | Anchor/boundary issue |
| Catastrophic backtrack | Nested quantifiers |
4. The Test Matrix
const testCases = [
// Should match
{ input: 'valid@email.com', expected: true },
{ input: 'test.user@domain.org', expected: true },
// Should NOT match
{ input: 'no-at-sign.com', expected: false },
{ input: '@no-local.com', expected: false },
// Edge cases
{ input: '', expected: false },
{ input: 'a@b.c', expected: true }, // Minimal valid
];---
Name
When Not to Regex
Description
Recognizing when regex is the wrong tool
When To Use
Before reaching for regex
Implementation
Alternatives to Regex
1. Don't Use Regex For
| Task | Use Instead |
|---|---|
| HTML parsing | DOM parser |
| JSON parsing | JSON.parse |
| URL parsing | URL constructor |
| CSV parsing | CSV library |
| Nested structures | Parser library |
| Simple contains | .includes() |
| Simple split | .split() |
| Simple replace | .replace(string, string) |
2. The HTML Warning
NEVER parse HTML with regex:
/<div>(.+?)<\/div>/ // BROKEN
Why? HTML is not regular.
- Tags can nest
- Attributes can contain >
- Comments break patterns
- Self-closing tags vary
Use: DOMParser, cheerio, etc.3. String Methods First
// REGEX OVERKILL
const hasPrefix = /^prefix/.test(str);
// SIMPLER
const hasPrefix = str.startsWith('prefix');
// REGEX OVERKILL
const parts = str.split(/,/);
// SIMPLER
const parts = str.split(',');4. Decision Tree
IS REGEX RIGHT?
Fixed string? → Use string methods
Nested structure? → Use parser
Complex grammar? → Use parser
Simple pattern? → Maybe regex
Variable pattern? → Regex
Performance critical? → Benchmark firstAnti-Patterns
---
Name
The Cryptic One-Liner
Description
Writing incomprehensible regex
Why Bad
Nobody can maintain it. Bugs hide in complexity. Future you will suffer.
What To Do Instead
Break into pieces. Use named groups. Comment thoroughly.
---
Name
The HTML Regex
Description
Parsing HTML or XML with regex
Why Bad
Will break on edge cases. Nested tags impossible. Leads to security issues.
What To Do Instead
Use proper parser. DOMParser for browser. Cheerio for Node.
---
Name
The Untested Regex
Description
Using regex without test cases
Why Bad
Edge cases will bite you. False confidence. Production failures.
What To Do Instead
Test valid inputs. Test invalid inputs. Test edge cases.
Regex Whisperer - Sharp Edges
Catastrophic Backtracking
Id
catastrophic-backtracking
Summary
Regex causes application hang or crash
Severity
high
Situation
Regex takes forever or crashes on certain inputs
Why
Nested quantifiers. Ambiguous patterns. Exponential backtracking.
Solution
Preventing ReDoS
The Problem
// DANGEROUS PATTERN
const pattern = /^(a+)+$/;
// This input causes exponential backtracking:
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaab'
// Why? The engine tries every way to match a+ before failingDangerous Patterns
| Pattern | Problem |
|---|---|
(a+)+ | Nested quantifiers |
| `(a | a)+` |
(.*)+ | Greedy nested |
(a+)* | Optional nested |
(.*?){n} | Non-greedy nested |
Safe Alternatives
// DANGEROUS
const bad = /(.*,)*$/;
// SAFE: Make inner group possessive or atomic
// (Not all engines support this)
// SAFE: Use negated class
const good = /([^,]*,)*$/;
// SAFE: Remove nesting
const better = /[^,]*(,[^,]*)*/;Prevention Checklist
| Check | Action |
|---|---|
| Nested quantifiers? | Flatten or use negated class |
| Overlapping alternatives? | Make mutually exclusive |
| Unknown input length? | Add timeout or limit |
| User-provided input? | Sanitize or limit length |
Runtime Protection
// Add timeout for user input
function safeMatch(pattern, input, timeoutMs = 100) {
const start = Date.now();
// Use streaming/iterative approach
// Or limit input length
if (input.length > 10000) {
throw new Error('Input too long');
}
return pattern.test(input);
}Symptoms
- CPU spike
- Request timeout
- Application hang
- "Too long" errors
Detection Pattern
slow regex|hang|timeout|backtrack
False Validation
Id
false-validation
Summary
Regex validates but shouldn't
Severity
high
Situation
Invalid data passes regex validation
Why
Missing anchors. Partial matches. Greedy behavior.
Solution
Bulletproof Validation
The Anchor Problem
// BROKEN: Matches anywhere in string
const emailBad = /[^\s@]+@[^\s@]+/;
'not an email abc@def.com junk'.match(emailBad); // Matches!
// FIXED: Anchored
const emailGood = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;Common Validation Gaps
| Gap | Example | Fix |
|---|---|---|
| No start anchor | /\d+/ matches 'a1b' | /^\d+/ |
| No end anchor | /^\d+/ matches '123abc' | /^\d+$/ |
| Missing length | /^\d+$/ accepts any length | /^\d{10}$/ |
| Missing boundaries | /cat/ matches 'category' | /\bcat\b/ |
Validation Layers
function validateEmail(input) {
// Layer 1: Basic regex
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input)) {
return false;
}
// Layer 2: Length check
if (input.length > 254) {
return false;
}
// Layer 3: Domain check (optional)
const domain = input.split('@')[1];
if (domain.length > 253) {
return false;
}
return true;
}Test Both Sides
// MUST test that invalid inputs FAIL
const invalidEmails = [
'',
'no-at-sign',
'@no-local',
'no-domain@',
'has spaces@domain.com',
'multiple@@at.com',
];
invalidEmails.forEach(email => {
expect(validateEmail(email)).toBe(false);
});Symptoms
- Invalid data in database
- Security bypasses
- But I validated it!
- Edge case failures
Detection Pattern
passed validation|shouldn't match|slipped through
Encoding Issues
Id
encoding-issues
Summary
Regex fails on unicode or special characters
Severity
medium
Situation
Pattern works in tests but fails in production
Why
Unicode handling. Different character sets. Invisible characters.
Solution
Unicode-Safe Patterns
The Unicode Problem
// BREAKS on non-ASCII
const wordBad = /\w+/; // Only matches [a-zA-Z0-9_]
// Works on any word character
const wordGood = /[\p{L}\p{N}_]+/u; // Needs 'u' flagFlag Requirements
| Flag | Purpose |
|---|---|
u | Unicode mode (required for \p{}) |
s | Dotall (. matches newline) |
m | Multiline (^ $ at line boundaries) |
Common Unicode Issues
| Issue | Example | Fix |
|---|---|---|
| Accents | café not matching | Use u flag |
| Emoji | 👍 breaking | Unicode property classes |
| RTL text | Arabic/Hebrew | Use u flag |
| Zero-width | Invisible chars | Explicit match |
Safe Character Classes
// Letters (any language)
const letter = /\p{L}/u;
// Numbers (any script)
const number = /\p{N}/u;
// Whitespace (all types)
const space = /\p{Z}/u;
// Word characters (unicode-aware)
const word = /[\p{L}\p{N}_]/u;Testing Unicode
const testStrings = [
'hello', // ASCII
'café', // Accented
'日本語', // Japanese
'مرحبا', // Arabic
'🎉 party', // Emoji
'hello\u200Bworld' // Zero-width space
];Symptoms
- Works in tests, fails production
- International names failing
- "Weird" characters breaking
- Empty matches
Detection Pattern
unicode|special character|doesn't match|encoding
Maintenance Nightmare
Id
maintenance-nightmare
Summary
Nobody can understand or modify the regex
Severity
medium
Situation
Regex is correct but unmaintainable
Why
Too complex. No comments. No tests.
Solution
Maintainable Regex
The Readability Debt
// UNMAINTAINABLE
const pattern = /^(?:(?:\+|00)33[\s.-]{0,3}(?:\(0\)[\s.-]{0,3})?|0)[1-9](?:(?:[\s.-]?\d{2}){4}|\d{2}(?:[\s.-]?\d{3}){2})$/;
// What does this match?
// How do I modify it?
// What edge cases exist?Refactoring Steps
// STEP 1: Break into pieces
const countryCode = '(?:(?:\\+|00)33[\\s.-]{0,3}(?:\\(0\\)[\\s.-]{0,3})?|0)';
const startDigit = '[1-9]';
const restDigits = '(?:(?:[\\s.-]?\\d{2}){4}|\\d{2}(?:[\\s.-]?\\d{3}){2})';
// STEP 2: Add comments
// French phone number pattern:
// - Starts with +33, 0033, or 0
// - Followed by 9 digits
// - Digits can be grouped with spaces, dots, or dashes
// STEP 3: Compose with explanation
const frenchPhone = new RegExp(
'^' +
countryCode + // Country code or leading 0
startDigit + // First digit (1-9)
restDigits + // Remaining 8 digits
'$'
);Documentation Template
/**
* Pattern: French Phone Number
*
* Matches:
* +33 1 23 45 67 89
* 0033123456789
* 01.23.45.67.89
*
* Rejects:
* 0023456789 (too short)
* +34... (wrong country)
*
* Limitations:
* - Doesn't validate area codes
* - Allows any separator combination
*/The Simplification Check
| If pattern is... | Consider |
|---|---|
| > 50 chars | Breaking into parts |
| > 3 groups | Named groups |
| Has nested quantifiers | Refactoring |
| No one understands | Rewriting simply |
Symptoms
- Fear of touching it
- Don't know what it does
- Copy-pasted from Stack Overflow
- No tests
Detection Pattern
what does this|don't understand|who wrote|scary regex
Regex Whisperer - Validations
Potential ReDoS Pattern
Id
nested-quantifiers
Severity
high
Type
pattern
Check
Regex should not have nested quantifiers
Pattern
\([^)][+][^)]\)[+]
Message
Pattern has nested quantifiers - potential ReDoS.
Fix Action
Flatten pattern or use negated character classes
Validation Without Anchors
Id
missing-anchors
Severity
medium
Type
conceptual
Check
Validation patterns should be anchored
Indicators
- Validation regex without ^ and $
- Partial match allowed
Message
Validation pattern may not be properly anchored.
Fix Action
Add ^ and $ anchors for full string validation
Untested Regex
Id
no-tests
Severity
medium
Type
conceptual
Check
Complex regex should have test cases
Indicators
- No test file
- No test cases
- Complex pattern without tests
Message
Regex has no test coverage.
Fix Action
Add test cases for valid, invalid, and edge cases
Complex Regex Without Comments
Id
uncommented-complex
Severity
medium
Type
conceptual
Check
Complex patterns should be documented
Indicators
- Long pattern without comments
- Multiple groups unnamed
- No explanation
Message
Complex regex is not documented.
Fix Action
Add comments, use named groups, or break into parts
HTML Parsing With Regex
Id
html-parsing
Severity
high
Type
conceptual
Check
HTML should not be parsed with regex
Indicators
- Pattern matching HTML tags
- <.*>
- Extracting from HTML
Message
Attempting to parse HTML with regex.
Fix Action
Use proper HTML parser (DOMParser, cheerio)
May Fail on Unicode
Id
missing-unicode
Severity
low
Type
conceptual
Check
Patterns handling text should consider unicode
Indicators
- \w without u flag
- International text expected
- User input
Message
Pattern may fail on unicode characters.
Fix Action
Add 'u' flag and use \p{L} for unicode letters