Regular Expressions
A regular expression ("regex") is a pattern for matching text. With one compact line you can check whether a string looks like a postcode, find every hashtag in a post, or reformat dates. The syntax looks cryptic at first, but a small core covers most practical needs.
Creating a regex
const literal = /cat/; const fromString = new RegExp("cat"); console.log(literal.test("concatenate")); console.log(fromString.test("dog"));
true false
A regex literal is written between slashes. The RegExp constructor is useful when the pattern is built from a variable. test() returns true if the pattern appears anywhere in the string.
Flags
Letters after the closing slash change how matching works:
| Flag | Meaning |
|---|---|
i | Case-insensitive |
g | Global — find all matches, not just the first |
m | Multi-line — ^ and $ match at each line |
u / v | Full Unicode support (emoji, character properties) |
s | . also matches newlines |
console.log(/hello/.test("Hello")); console.log(/hello/i.test("Hello")); console.log("a1b2c3".replace(/\d/, "#")); console.log("a1b2c3".replace(/\d/g, "#"));
false true a#b2c3 a#b#c#
Character classes
| Pattern | Matches |
|---|---|
. | Any character except newline |
\d / \D | A digit / a non-digit |
\w / \W | A word character (letter, digit, _) / anything else |
\s / \S | Whitespace / non-whitespace |
[abc] | Any one of a, b or c |
[a-z], [0-9] | A range |
[^abc] | Any character except a, b or c |
Quantifiers and anchors
| Pattern | Meaning |
|---|---|
* | 0 or more |
+ | 1 or more |
? | 0 or 1 (optional) |
{3}, {2,4}, {2,} | Exactly 3, between 2 and 4, at least 2 |
^ / $ | Start / end of the string |
\b | A word boundary |
a|b | a or b |
const zip = /^\d{5}(-\d{4})?$/; console.log(zip.test("90210"), zip.test("90210-1234"), zip.test("9021")); const hexColor = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i; console.log(hexColor.test("#D6336C"), hexColor.test("#fff"), hexColor.test("red")); const username = /^[a-z][a-z0-9_]{2,15}$/; console.log(username.test("ada_99"), username.test("9lives"));
true true false true true false true false
Without ^ and $, a pattern can match part of a string — /\d{5}/ would accept "abc123456xyz". Anchor validation patterns at both ends.
Finding matches
const post = "Loving #javascript and #webdev today! #js"; console.log(post.match(/#\w+/)); console.log(post.match(/#\w+/g)); console.log(post.search(/#/));
[ '#javascript', index: 7, input: 'Loving #javascript and #webdev today! #js', groups: undefined ] [ '#javascript', '#webdev', '#js' ] 7
Without g, match returns details of the first match (or null). With g, it returns an array of every matching string.
Capture groups
Parentheses capture part of a match. Named groups, written (?<name>…), make the result much more readable:
const date = "Due: 2026-10-06"; const m = date.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/); console.log(m.groups.year, m.groups.month, m.groups.day); console.log(date.replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1"));
2026 10 06 Due: 06/10/2026
In a replacement string, $1, $2… refer to the captured groups.
Looping over all matches
const prices = "Tea $3.50, Cake $4.25, Juice $5"; for (const m of prices.matchAll(/(\w+) \$(\d+(?:\.\d+)?)/g)) { console.log(m[1], "→", Number(m[2])); }
Tea → 3.5 Cake → 4.25 Juice → 5
(?:…) groups without capturing. matchAll requires the g flag and gives full details, including groups, for every match.
Replacing with a function
const text = "the quick brown fox"; console.log(text.replace(/\b\w/g, ch => ch.toUpperCase())); const message = "Order 3 apples and 12 pears"; console.log(message.replace(/\d+/g, n => String(Number(n) * 2)));
The Quick Brown Fox Order 6 apples and 24 pears
Escaping special characters
Characters like . * + ? ( ) [ ] { } ^ $ | \ / have special meanings. To match them literally, escape them with a backslash: /\$\d+\.\d{2}/ matches $4.99. When building a pattern from user input, escape it first — newer engines provide RegExp.escape() for exactly this.
includes, startsWith, split) when they're enough. Don't try to fully validate email addresses with a regex; check for an @ and send a confirmation email instead.