Last updated
Email Address Validation
Testing an email regex against various inputs:
Pattern: ^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$
Flags: i (case-insensitive)
Test cases:
user@example.com → MATCH ✓
user.name+tag@example.com → MATCH ✓
user@subdomain.example.co.uk → MATCH ✓
USER@EXAMPLE.COM → MATCH ✓ (case-insensitive flag)
user@example → NO MATCH ✗ (no TLD)
@example.com → NO MATCH ✗ (no local part)
user @example.com → NO MATCH ✗ (space not allowed)
user@.example.com → NO MATCH ✗ (dot after @)
Phone Number Validation
US phone number in various formats:
Pattern: ^(\+1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$
Test cases:
(555) 123-4567 → MATCH ✓
555-123-4567 → MATCH ✓
555.123.4567 → MATCH ✓
5551234567 → MATCH ✓
+1 555 123 4567 → MATCH ✓
+1-555-123-4567 → MATCH ✓
555-123-456 → NO MATCH ✗ (only 9 digits)
555-123-45678 → NO MATCH ✗ (10+ digits)
(555 123-4567 → NO MATCH ✗ (unmatched parenthesis)
URL Validation
Validating HTTP/HTTPS URLs:
Pattern: ^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$
Test cases:
https://example.com → MATCH ✓
http://www.example.com/path → MATCH ✓
https://sub.example.co.uk/path?q=1 → MATCH ✓
https://example.com:8080/api → MATCH ✓
ftp://example.com → NO MATCH ✗ (not http/https)
example.com → NO MATCH ✗ (no protocol)
https:// → NO MATCH ✗ (no domain)
Date Format Validation
Validating ISO 8601 date format (YYYY-MM-DD):
Pattern: ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
Test cases:
2024-03-17 → MATCH ✓
2024-01-01 → MATCH ✓
2024-12-31 → MATCH ✓
2024-13-01 → NO MATCH ✗ (month 13 invalid)
2024-00-15 → NO MATCH ✗ (month 00 invalid)
2024-03-32 → NO MATCH ✗ (day 32 invalid)
2024-3-17 → NO MATCH ✗ (month must be 2 digits)
24-03-17 → NO MATCH ✗ (year must be 4 digits)
Note: This validates format only, not calendar validity
(e.g., 2024-02-30 would match but is not a real date)
IP Address Validation
IPv4 address validation:
Pattern: ^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$
Test cases:
192.168.1.1 → MATCH ✓
10.0.0.1 → MATCH ✓
255.255.255.255 → MATCH ✓
0.0.0.0 → MATCH ✓
256.1.1.1 → NO MATCH ✗ (256 > 255)
192.168.1 → NO MATCH ✗ (only 3 octets)
192.168.1.1.1 → NO MATCH ✗ (5 octets)
192.168.01.1 → MATCH ✓ (leading zero allowed by pattern)
Capture Group Testing
Extracting parts of a string with named capture groups:
Pattern: ^(?P<year>\d{4})-(?P<month>0[1-9]|1[0-2])-(?P<day>0[1-9]|[12]\d|3[01])$
Input: 2024-03-17
Capture groups:
Group 0 (full match): "2024-03-17"
Group 1 (year): "2024"
Group 2 (month): "03"
Group 3 (day): "17"
Named groups (Python/JavaScript):
year: "2024"
month: "03"
day: "17"
Generated Validation Code
JavaScript validation function generated from a tested pattern:
// Email validation — generated from tested pattern
const EMAIL_REGEX = /^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$/i;
function validateEmail(email) {
if (!email || typeof email !== 'string') {
return { valid: false, error: 'Email is required' };
}
if (!EMAIL_REGEX.test(email)) {
return { valid: false, error: 'Please enter a valid email address' };
}
return { valid: true };
}
// Usage
validateEmail('user@example.com') // { valid: true }
validateEmail('not-an-email') // { valid: false, error: '...' }
Regex Flags Reference
How different flags affect pattern matching:
Pattern: hello
Without flags:
"Hello World" → NO MATCH (case-sensitive)
"hello world" → MATCH
With i flag (case-insensitive):
"Hello World" → MATCH
"HELLO WORLD" → MATCH
Pattern: ^start
Without m flag:
"start of string\nsecond line" → MATCH (^ = start of string)
With m flag (multiline):
"first line\nstart of line" → MATCH (^ = start of each line)
Pattern: .+
Without s flag:
"line1\nline2" → matches "line1" and "line2" separately
With s flag (dotall):
"line1\nline2" → matches "line1\nline2" (dot matches newline)
Performance Testing — Catastrophic Backtracking
Patterns that can cause exponential slowdown:
// DANGEROUS — catastrophic backtracking
Pattern: (a+)+$
Input: "aaaaaaaaaaaaaaaaaaaaaaaaaaab"
Result: Hangs for seconds or minutes
// Why: The engine tries every possible way to group the 'a's
// before determining the 'b' at the end doesn't match $
// SAFE alternative
Pattern: a+$
Input: "aaaaaaaaaaaaaaaaaaaaaaaaaaab"
Result: Fails instantly
// Another dangerous pattern
Pattern: (a|aa)+$
// SAFE alternative: a+$
// The validator tests your pattern against adversarial inputs
// and reports execution time to catch these issues