Regular expressions are powerful for text matching and manipulation. This guide covers practical patterns for common tasks.
Basic Syntax#
1// Literal notation
2const pattern = /hello/;
3
4// Constructor (for dynamic patterns)
5const dynamic = new RegExp('hello', 'i');
6
7// Flags
8/pattern/g; // Global - find all matches
9/pattern/i; // Case insensitive
10/pattern/m; // Multiline
11/pattern/s; // Dotall - . matches newlines
12/pattern/u; // UnicodeCommon Patterns#
Email Validation#
// Simple email pattern
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
emailPattern.test('user@example.com'); // true
emailPattern.test('invalid-email'); // falseURL Validation#
const urlPattern = /^https?:\/\/[\w\-.]+(:\d+)?(\/[\w\-._~:/?#[\]@!$&'()*+,;=]*)?$/;
urlPattern.test('https://example.com'); // true
urlPattern.test('http://localhost:3000/path'); // truePhone Numbers#
1// US phone numbers
2const phonePattern = /^\(?(\d{3})\)?[-.\s]?(\d{3})[-.\s]?(\d{4})$/;
3
4phonePattern.test('(555) 123-4567'); // true
5phonePattern.test('555.123.4567'); // true
6phonePattern.test('5551234567'); // truePassword Validation#
// At least 8 chars, one uppercase, one lowercase, one number
const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
passwordPattern.test('Password1'); // true
passwordPattern.test('password'); // false (no uppercase or number)Capturing Groups#
1// Extract parts of a match
2const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
3const match = '2024-01-15'.match(datePattern);
4
5console.log(match[1]); // "2024" (year)
6console.log(match[2]); // "01" (month)
7console.log(match[3]); // "15" (day)
8
9// Named groups
10const namedPattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
11const namedMatch = '2024-01-15'.match(namedPattern);
12
13console.log(namedMatch.groups.year); // "2024"
14console.log(namedMatch.groups.month); // "01"String Methods#
1// test() - returns boolean
2/hello/.test('hello world'); // true
3
4// match() - returns matches
5'hello world'.match(/\w+/g); // ['hello', 'world']
6
7// replace() - replace matches
8'hello world'.replace(/world/, 'there'); // 'hello there'
9
10// replaceAll() - replace all matches
11'a-b-c'.replaceAll(/-/g, '_'); // 'a_b_c'
12
13// split() - split by pattern
14'a, b, c'.split(/,\s*/); // ['a', 'b', 'c']
15
16// search() - returns index
17'hello world'.search(/world/); // 6Replace with Functions#
1// Dynamic replacement
2const text = 'I have 2 apples and 3 oranges';
3
4const result = text.replace(/\d+/g, (match) => {
5 return parseInt(match) * 2;
6});
7
8console.log(result); // "I have 4 apples and 6 oranges"
9
10// With capture groups
11'John Doe'.replace(/(\w+) (\w+)/, '$2, $1'); // "Doe, John"Lookahead and Lookbehind#
1// Positive lookahead (?=)
2// Match 'foo' only if followed by 'bar'
3'foobar foobaz'.match(/foo(?=bar)/g); // ['foo']
4
5// Negative lookahead (?!)
6// Match 'foo' only if NOT followed by 'bar'
7'foobar foobaz'.match(/foo(?!bar)/g); // ['foo']
8
9// Positive lookbehind (?<=)
10// Match digits after $
11'$100 €200'.match(/(?<=\$)\d+/g); // ['100']
12
13// Negative lookbehind (?<!)
14// Match digits NOT after $
15'$100 200'.match(/(?<!\$)\d+/g); // ['200']Practical Examples#
Extract All URLs#
const text = 'Visit https://example.com or http://test.org';
const urls = text.match(/https?:\/\/[^\s]+/g);
// ['https://example.com', 'http://test.org']Sanitize Input#
function sanitizeFilename(name) {
return name.replace(/[^a-z0-9\-_.]/gi, '_');
}
sanitizeFilename('My File (1).txt'); // "My_File__1_.txt"Parse CSV Line#
1function parseCSVLine(line) {
2 const pattern = /(?:^|,)("(?:[^"]|"")*"|[^,]*)/g;
3 const values = [];
4 let match;
5
6 while ((match = pattern.exec(line)) !== null) {
7 let value = match[1];
8 if (value.startsWith('"')) {
9 value = value.slice(1, -1).replace(/""/g, '"');
10 }
11 values.push(value);
12 }
13
14 return values;
15}Highlight Search Terms#
1function highlightTerms(text, searchTerms) {
2 const pattern = new RegExp(`(${searchTerms.join('|')})`, 'gi');
3 return text.replace(pattern, '<mark>$1</mark>');
4}
5
6highlightTerms('Hello world', ['hello', 'world']);
7// "<mark>Hello</mark> <mark>world</mark>"Performance Tips#
1// Compile regex once, reuse
2const pattern = /\d+/g; // Outside loop
3
4for (const item of items) {
5 pattern.lastIndex = 0; // Reset for global patterns
6 if (pattern.test(item)) { }
7}
8
9// Avoid catastrophic backtracking
10// ❌ Bad: (a+)+ can hang on certain inputs
11// ✅ Good: Use atomic groups or be specificRegular expressions are powerful but can be hard to read. Add comments for complex patterns and consider named groups for clarity.