Regular Expressions Explained: The Visual Guide
Regex doesn't have to be cryptic. Let me decode it for you.
What Is Regex?
Regex = pattern matching for text. Think "find and replace on steroids."
Text: "My email is alex@example.com and my phone is 555-123-4567"
Regex: \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b
Match: alex@example.com
The Core Syntax (Cheat Sheet)
Character Classes
. Any character (except newline)
\d Digit [0-9]
\D Not a digit [^0-9]
\w Word character [a-zA-Z0-9_]
\W Not a word character
\s Whitespace (space, tab, newline)
\S Not whitespace
[abc] Any of a, b, or c
[a-z] Any lowercase letter
[0-9] Any digit (same as \d)
[^abc] NOT a, b, or c
Quantifiers (How Many)
* Zero or more
+ One or more
? Zero or one (optional)
{3} Exactly 3
{2,5} Between 2 and 5
{3,} 3 or more
Anchors (Position)
^ Start of string
$ End of string
\b Word boundary
\B Not a word boundary
Groups and Alternation
(abc) Capture group — remember the match
(?:abc) Non-capturing group — match but don't remember
a|b Either a OR b
\1 Reference to first capture group
Real-World Examples
1. Email Validation
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
emailRegex.test('alex@example.com'); // true
emailRegex.test('not-an-email'); // false
emailRegex.test('user@sub.domain.co.uk'); // true
2. URL Extraction
const urlRegex = /https?:\/\/(www\.)?[a-zA-Z0-9-]+\.[a-zA-Z]{2,}[^\s]*/g;
const text = 'Visit https://example.com or http://test.org/path?q=1';
text.match(urlRegex);
// ['https://example.com', 'http://test.org/path?q=1']
3. Phone Number Formatting
// Match US phone numbers in various formats
const phoneRegex = /(\d{3})[-.)]?(\d{3})[-.)]?(\d{4})/;
const phones = [
'555-123-4567',
'(555) 123-4567',
'555.123.4567',
'5551234567',
];
phones.forEach(phone => {
const match = phone.match(phoneRegex);
if (match) {
const formatted = `(${match[1]}) ${match[2]}-${match[3]}`;
console.log(`${phone} → ${formatted}`);
}
});
// 555-123-4567 → (555) 123-4567
// (555) 123-4567 → (555) 123-4567
// 555.123.4567 → (555) 123-4567
// 5551234567 → (555) 123-4567
4. Password Strength
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$/;
// Requires: lowercase + uppercase + digit + special char + 8+ chars
passwordRegex.test('Password1!'); // true
passwordRegex.test('weak'); // false
passwordRegex.test('NoSpecial1'); // false
5. HTML Tag Extraction
const htmlRegex = /<(\w+)([^>]*)>(.*?)<\/\1>/gs;
const html = '<div class="test">Hello <span>world</span></div>';
const matches = [...html.matchAll(htmlRegex)];
matches.forEach(match => {
console.log(`Tag: ${match[1]}, Attrs: ${match[2]}, Content: ${match[3]}`);
});
// Tag: div, Attrs: class="test", Content: Hello <span>world</span>
// Tag: span, Attrs: , Content: world
6. String Cleaning
// Remove HTML tags
'Hello <b>world</b>'.replace(/<[^>]*>/g, ''); // "Hello world"
// Remove extra whitespace
' too many spaces '.replace(/\s+/g, ' ').trim(); // "too many spaces"
// Convert to title case
'the quick brown fox'.replace(
/\b\w/g,
char => char.toUpperCase()
); // "The Quick Brown Fox"
// Remove numbers from string
'Order #12345 confirmed'.replace(/\d+/g, ''); // "Order # confirmed"
// Replace multiple dots with single dot
'file....name...txt'.replace(/\.+/g, '.'); // "file.name.txt"
7. Find and Replace with Groups
// Reformat date from MM/DD/YYYY to YYYY-MM-DD
const dateStr = 'Date: 12/31/2026 and 01/15/2026';
const reformatted = dateStr.replace(
/(\d{2})\/(\d{2})\/(\d{4})/g,
'$3-$1-$2'
);
// "Date: 2026-12-31 and 2026-01-15"
// Swap first and last name
const names = 'Smith, John; Doe, Jane';
const swapped = names.replace(
/(\w+),\s*(\w+)/g,
'$2 $1'
);
// "John Smith; Jane Doe"
JavaScript Regex Methods
// test() — Does it match? (boolean)
/hello/.test('hello world'); // true
// match() — Find all matches
'abc123abc'.match(/abc/g); // ['abc', 'abc']
// matchAll() — Find matches with groups
const text = 'Jan 5 and Feb 12';
[...text.matchAll(/(\w+) (\d+)/g)].forEach(m => {
console.log(`${m[1]}: ${m[2]}`);
});
// replace() — Find and replace
'hello world'.replace(/world/, 'regex'); // "hello regex"
// replaceAll() — Replace ALL occurrences
'aabbcc'.replaceAll(/b/g, 'x'); // "aaxxcc"
// search() — Find index of match
'hello world'.search(/world/); // 6
// split() — Split string by pattern
'a1b2c3'.split(/\d/); // ['a', 'b', 'c', '']
Common Patterns Library
const patterns = {
email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
url: /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}$/,
ipv4: /^(\d{1,3}\.){3}\d{1,3}$/,
date: /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/,
hexColor: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/,
usPhone: /^(\+1)?[\s-]?\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/,
username: /^[a-zA-Z0-9_-]{3,20}$/,
strongPassword: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$/,
creditCard: /^(\d{4}[-\s]?){3}\d{4}$/,
slug: /^[a-z0-9]+(?:-[a-z0-9]+)*$/,
};
Pro Tips
// 1. Use 'g' flag for global (all matches)
'aaa'.match(/a/); // ['a'] — first match only
'aaa'.match(/a/g); // ['a', 'a', 'a'] — all matches
// 2. Use 'i' flag for case-insensitive
/Hello/.test('hello'); // false
/Hello/i.test('hello'); // true
// 3. Use 's' flag for dotAll (dot matches newlines)
/a.b/.test('a\nb'); // false
/a.b/s.test('a\nb'); // true
// 4. Escape special characters with backslash
// Special chars: . * + ? ^ $ { } [ ] \ | ( )
const safe = 'hello.world'.replace(/\./g, '\\.'); // "hello\\.world"
// 5. Use non-capturing groups (?:) for performance
// Bad: /(?:a|b)(?:c|d)/ — doesn't create capture groups
// Good for complex patterns where you don't need groups
What's the most complex regex you've ever written?
Follow @armorbreak for more developer guides.
Top comments (0)