Regular Expressions
Regular expressions (regex) describe patterns in text. JavaScript provides the RegExp object and string methods (match, search, replace, split) for searching, validating, and transforming strings.
Creating a RegExp
// Literal syntax (preferred when pattern is known)
const emailPattern = /^[\w.-]+@[\w.-]+\.\w+$/;
// Constructor (when pattern is built dynamically)
const domain = 'example.com';
const dynamic = new RegExp(`@${domain}$`);
Literal syntax cannot use variables; the constructor accepts runtime strings.
Flags
| Flag | Meaning |
|---|---|
g |
Global — find all matches, not just the first |
i |
Case insensitive |
m |
Multiline — ^ and $ match line boundaries |
s |
Dotall — . matches newline characters |
u |
Unicode — correct handling of astral symbols |
y |
Sticky — match only at lastIndex position |
/he/lgi.test('HeLLo'); // true (case insensitive)
'aaa'.match(/a/g); // ['a', 'a', 'a']
String Methods
const text = 'Hello world, hello JavaScript';
text.match(/hello/gi); // ['Hello', 'hello']
text.search(/world/); // 6 (index of first match, or -1)
text.replace(/hello/gi, 'Hi'); // 'Hi world, Hi JavaScript'
text.split(/,\s*/); // ['Hello world', 'hello JavaScript']
replace with the g flag replaces all matches; without g, only the first match is replaced.
RegExp Methods
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const date = '2024-06-13';
dateRegex.test(date); // true — boolean check
dateRegex.exec(date);
// ['2024-06-13', '2024', '06', '13', index: 0, input: '2024-06-13', groups: undefined]
Use test() for validation (boolean); use exec() or match() when you need captured groups.
Character Classes and Shorthands
/[abc]/ // a, b, or c
/[^abc]/ // any character EXCEPT a, b, c
/[a-zA-Z]/ // any letter
/[0-9]/ // any digit
/\w/ // word char: [a-zA-Z0-9_]
/\d/ // digit: [0-9]
/\s/ // whitespace: space, tab, newline
./ // any character (except newline, unless s flag)
Quantifiers
| Pattern | Meaning |
|---|---|
a* |
Zero or more |
a+ |
One or more |
a? |
Zero or one |
a{3} |
Exactly 3 |
a{2,5} |
Between 2 and 5 |
a+? |
Lazy (non-greedy) one or more |
Greedy vs lazy:
'<b>x</b>'.match(/<.*>/); // ['<b>x</b>'] — greedy, matches widest
'<b>x</b>'.match(/<.*?>/); // ['<b>'] — lazy, matches narrowest
Groups and Capturing
const re = /(\w+)@(\w+)\.(\w+)/;
const match = '[email protected]'.match(re);
console.log(match[0]); // '[email protected]' (full match)
console.log(match[1]); // 'user'
console.log(match[2]); // 'mail'
console.log(match[3]); // 'com'
Named Groups (ES2018)
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const { groups } = re.exec('2024-06-13');
console.log(groups.year); // '2024'
console.log(groups.month); // '06'
console.log(groups.day); // '13'
Non-Capturing Groups
/(?:https?):\/\//.test('https://example.com'); // match without capturing
Lookahead and Lookbehind
// Positive lookahead: password with digit
/^(?=.*\d).{8,}$/.test('abc12345'); // true
// Negative lookahead: no spaces
/^\S+$/.test('no spaces'); // true
// Lookbehind (ES2018)
/(?<=\$)\d+/.exec('Price: $99'); // ['99']
Common Validation Patterns
/^\d+$/ // digits only
/^[a-zA-Z]+$/ // letters only
/^\d{3}-\d{3}-\d{4}$/ // US phone: 123-456-7890
/^#[0-9A-Fa-f]{6}$/ // hex color: #FF5733
/^(https?):\/\/\S+$/ // URL starting with http/https
These are educational patterns — production email/URL validation needs more robust rules or dedicated libraries.
replace with Callback
'hello world'.replace(/\b\w/g, char => char.toUpperCase());
// 'Hello World'
'price: 10, tax: 2'.replace(/\d+/g, n => String(Number(n) * 2));
// 'price: 20, tax: 4'
Best Practices
- Test edge cases — empty strings, unicode, very long inputs.
- Prefer named groups for readable capture references.
- Avoid catastrophic backtracking — nested quantifiers like
(a+)+on long strings can hang the browser. - Use dedicated libraries (e.g.,
validator.js) for production email/URL validation. - Store complex patterns in constants with descriptive names.
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
. doesn’t match newline |
Default dot behavior | Add s flag or use [\s\S] |
| Only first match replaced | Missing g flag |
Add /pattern/g |
Unexpected null from match |
No match found | Check with test() first or use optional chaining |
\b word boundary fails |
Unicode or special chars | Use u flag; verify boundary context |
| Regex hangs on long input | Catastrophic backtracking | Simplify pattern; use atomic groups or limits |
Regular expressions are powerful for validation, parsing, and text processing. Master the basics here, then reach for libraries when patterns become complex or security-critical.