Regular expressions are patterns used to match character combinations in strings. In JavaScript, they are implemented as RegExp objects and integrate with both RegExp instance methods (exec, test) and String prototype methods (match, matchAll, replace, search, split).
Constructing Regular Expressions
Two primary approaches exist:
Literal notation: Defined using forward slashes.
const pattern = /hello\d+/;
This form compiles at parse time—ideal for static patterns and better performance.
Constructor syntax: Built dynamically via RegExp.
const digits = '123';
const pattern = new RegExp(`hello${digits}`, 'i');
Use this when the pattern is derived from runtime data (e.g., user input), since it supports interpolated strings and flags.
Pattern Composition
Patterns combine literal characters (e.g., /cat/) and metacharacters that convey logic (e.g., /c[aeiou]t/, /\d{3}-\d{2}-\d{4}/). Parentheses () create capturing groups, enabling extraction and reuse of matched substrings.
Literal Matching
A pattern like /dog/ matches only the exact sequence 'dog'. It succeeds in 'My dog barks' but fails in 'dogma' if anchored or in 'D.O.G.' without case-insensitive or dot-handling flags.
Metacharacters and Quantifiers
To express variability, use quantifiers and assertions:
*: zero or more of the preceding element (/ab*/matches'a','ab','abb').+: one or more (/\w+/matches'hello'in'hello world').?: zero or one; also toggles lazy matching when appended to another quantifier (/a+?/matches'a'in'aaab', not'aaa').{n,m}: between n and m occurrences (/\d{2,4}/matches'12','123','1234').^and$: assert start and end of input (or line withmflag).\b: word boundary (/\bcat\b/matches'cat'but not'scatter').|: alternation (/red|blue/matches either substring).
Character Classes
\d: digit ([0-9]).\w: word character ([A-Za-z0-9_]).\s: whitespace ([ \f\n\r\t\v\u0020\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]).[abc]: matches any ofa,b, orc.[^xyz]: matches any character exceptx,y, orz.
Assertions
(?=...): positive lookahead — matches only if followed by the pattern.(?!...): negative lookahead — matches only if not followed by the pattern.(?<=...): positive lookbehind — matches only if preceded by the pattern.(?<!...): negative lookbehind — matches only if not preceded by the pattern.
Groups
(x): capturing group — stores matched content for backreference ($1,$2) or programmatic access (result[1]).(?:x): non-capturing group — applies grouping logic without memory overhead.
Escaping Special Characters
To treat a metacharacter literally (e.g., match . instead of "any character"), prefix it with \\:
const literalDot = /\./; // matches '.'
const pathPattern = /C:\\Users\\[^\\]+/; // matches Windows paths
When building from strings, double-escape backslashes:
const patternStr = 'C:\\Users\\';
const re = new RegExp(patternStr + '[^\\]+');
For safe dynamic escaping of arbitrary strings:
function escapeForRegex(str) {
return str.replace(/[\[\]{}()*+?.^$|\\]/g, '\\$&');
}
Core Methods
| Method | Context | Return | Notes |
|---|---|---|---|
exec() |
RegExp |
Array or null |
Returns full match + captures; updates lastIndex with g flag. |
test() |
RegExp |
boolean |
Fast boolean check; no capture data. |
match() |
String |
Array or null |
Like exec(), but called on string. With g, returns matches only (no groups). |
matchAll() |
String |
Iterator |
Yields all matches with full detail (including groups). |
replace() |
String |
string |
Substitutes matches; supports $1, $2, functions. |
search() |
String |
number |
Returns first match index or -1. |
split() |
String |
Array |
Splits on matches; empty strings retained if adjacent delimiters. |
Example using exec with global state:
const re = /\b(\w+)\b/g;
const text = 'Hello world! Hello again!';
let match;
while ((match = re.exec(text)) !== null) {
console.log(`Found '${match[0]}' at position ${match.index}`);
// Captured group: match[1]
}
Flags
Flags modify matching behavior and are appended after the closing slash (literal) or passed as second argument (constructor):
g: global — finds all matches, not just the first.i: case-insensitive.m: multiline —^/$match line boundaries.s: dotAll —.matches newlines.u: Unicode — enables full Unicode support (e.g.,\u{1F600}emojis).y: sticky — matches only fromlastIndex; useful for incremental parsing.
Example with multiple flags:
const re = /\bhello\b/giu;
// or
const re2 = new RegExp('\\bhello\\b', 'giu');
Practical Examples
Reordering name components:
const fullName = 'Jane Doe';
const swapped = fullName.replace(/^(\w+)\s+(\w+)$/, '$2, $1');
// → 'Doe, Jane'
Validating US phone numbers (flexible formatting):
const phoneRE = /^(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}$/;
console.log(phoneRE.test('(123) 456-7890')); // false — space breaks pattern
console.log(phoneRE.test('(123)456-7890')); // true
Splititng and transforming delimited data:
const raw = 'Alice ; Bob ; Charlie';
const names = raw.split(/\s*;\s*/).map(n => n.trim());
const formatted = names.map(name => name.replace(/^(\w+)\s+(\w+)$/, '$2, $1'));
// → ['Bob, Alice', 'Charlie'] (if two-part names only)