Introduction
Regular expressions (regex) are patterns for matching text. They're powerful but cryptic—a double-edged sword that can validate emails in one line or create maintenance nightmares. Understanding the basics unlocks powerful text processing capabilities.
Key Concepts
Regular Expression: A pattern that describes a set of strings.
Literal: Characters that match themselves (like hello).
Metacharacters: Special characters with meaning (like ., *, +).
Real World Context
Form validation, search and replace, parsing logs, extracting data from strings—regex appears throughout web development. Most validation libraries use regex under the hood.
Deep Dive
Creating Regular Expressions
javascript// Literal syntax (preferred for static patterns) const regex1 = /hello/; // Constructor syntax (for dynamic patterns) const pattern = 'hello'; const regex2 = new RegExp(pattern); // With flags const regex3 = /hello/gi; // g=global, i=case-insensitive const regex4 = new RegExp('hello', 'gi');
Testing and Matching
javascriptconst regex = /world/i; // test() - returns boolean regex.test('Hello World'); // true // match() - returns matches 'Hello World'.match(regex); // ['World'] 'Hello World World'.match(/world/gi); // ['World', 'World'] // exec() - detailed info (use in loop for global) regex.exec('Hello World'); // ['World', index: 6, input: '...']
Basic Patterns
javascript// Literals /hello/.test('hello world'); // true // Character classes /[aeiou]/.test('hello'); // true (matches any vowel) /[0-9]/.test('abc123'); // true /[^0-9]/.test('abc123'); // true (^ negates in character class) // Predefined classes /\d/.test('abc123'); // true (digit) /\w/.test('hello'); // true (word char: a-z, A-Z, 0-9, _) /\s/.test('hello world'); // true (whitespace) /\D/.test('abc'); // true (non-digit, uppercase negates) // Any character (except newline) /./.test('x'); // true
Flags
javascript// g - global (find all matches, not just first) 'hello hello'.match(/hello/); // ['hello'] 'hello hello'.match(/hello/g); // ['hello', 'hello'] // i - case insensitive /hello/i.test('HELLO'); // true // m - multiline (^ and $ match line boundaries) /^hello/m.test('world\nhello'); // true // s - dotAll (. matches newlines too) /hello.world/s.test('hello\nworld'); // true // u - unicode (proper unicode handling) /\p{L}/u.test('π'); // true (any letter) // d - indices (ES2022, capture group indices) const result = /(?<name>\w+)/.exec('hello');
Common Pitfalls
- Escaping special characters:
.matches any char;\.matches literal dot. - Greedy by default:
.*matches as much as possible. - Global flag changes exec(): Must loop; index advances between calls.
Best Practices
- Use literal syntax when possible:
/pattern/is cleaner thannew RegExp(). - Use named groups for clarity:
(?<year>\d{4})instead of(\d{4}). - Escape user input:
RegExp.escape()or manual escaping for dynamic patterns. - Comment complex regex: Or use verbose mode with libraries.
Summary
Regex patterns match text using literals and metacharacters. Use /pattern/flags syntax. test() returns boolean, match() returns matches. Flags modify behavior: g for global, i for case-insensitive, m for multiline. Always escape special characters in literal strings.
Code Examples
// Literal syntax (preferred for static patterns)
const regex1 = /hello/;
// Constructor syntax (for dynamic patterns)
const pattern = 'hello';
const regex2 = new RegExp(pattern);
// With flags
const regex3 = /hello/gi; // g=global, i=case-insensitive
const regex4 = new RegExp('hello', 'gi');const regex = /world/i;
// test() - returns boolean
regex.test('Hello World'); // true
// match() - returns matches
'Hello World'.match(regex); // ['World']
'Hello World World'.match(/world/gi); // ['World', 'World']
// exec() - detailed info (use in loop for global)
regex.exec('Hello World'); // ['World', index: 6, input: '...']