Regular Expressions
A regular expression (regex) is a pattern that describes a set of character combinations in a string. We use regular expressions to search text, to validate text, and to change text.
Creating Regular Expressions
Two ways to create a regex:
// Literal syntax (preferred when pattern is constant)
const regex1 = /hello/;
// Constructor syntax (when pattern is dynamic)
const regex2 = new RegExp("hello");
// With flags
const regex3 = /hello/gi;
const regex4 = new RegExp("hello", "gi");
Flags
| Flag | Description |
|---|---|
d |
Indices - include start/end indices in matches |
g |
Global - find all matches, not just the first |
i |
Case-insensitive matching |
m |
Multiline - ^ and $ match line starts/ends |
s |
Dotall - . matches newlines too |
u |
Unicode - treat pattern as Unicode |
v |
Unicode sets - enables set notation/intersections |
y |
Sticky - match at exact position |
u and v are both Unicode-aware modes, but they are mutually exclusive on the same regex.
const text = "Hello HELLO hello";
console.log(text.match(/hello/)); // ["hello"] (first match only)
console.log(text.match(/hello/g)); // ["hello"] (global, case-sensitive)
console.log(text.match(/hello/gi)); // ["Hello", "HELLO", "hello"]
Basic Patterns
Literal Characters
/cat/.test("catalog"); // true - contains "cat"
Character Classes
| Pattern | Matches |
|---|---|
[abc] |
Any of a, b, or c |
[^abc] |
Any character except a, b, c |
[a-z] |
Any lowercase letter |
[A-Z] |
Any uppercase letter |
[0-9] |
Any digit |
[a-zA-Z0-9] |
Any alphanumeric character |
/[aeiou]/.test("hello"); // true (has vowels)
/[^0-9]/.test("abc123"); // true (has non-digits)
/[A-Z]/.test("Hello"); // true (has uppercase)
Shorthand Character Classes
| Pattern | Equivalent | Matches |
|---|---|---|
\d |
[0-9] |
Digit |
\D |
[^0-9] |
Non-digit |
\w |
(roughly) [A-Za-z0-9_] |
Word character |
\W |
Inverse of \w |
Non-word character |
\s |
[ \t\n\r\f\v] |
Whitespace |
\S |
[^ \t\n\r\f\v] |
Non-whitespace |
. |
(almost any) | Any char except newline |
/\d{3}/.test("abc123"); // true (three digits)
/\w+/.test("hello_world"); // true (word characters)
/\s/.test("hello world"); // true (has whitespace)
Quantifiers
| Pattern | Meaning |
|---|---|
* |
0 or more |
+ |
1 or more |
? |
0 or 1 |
{n} |
Exactly n |
{n,} |
n or more |
{n,m} |
Between n and m |
/bo*/.test("b"); // true (0 o's)
/bo*/.test("boooo"); // true (4 o's)
/bo+/.test("b"); // false (needs at least 1 o)
/bo+/.test("bo"); // true
/colou?r/.test("color"); // true (u is optional)
/colou?r/.test("colour"); // true
/\d{3}-\d{4}/.test("555-1234"); // true (phone format)
Greedy vs Lazy
Quantifiers are greedy by default (match as much as possible). Add ? to make them lazy:
const html = "<div>content</div>";
// Greedy - matches everything between first < and last >
console.log(html.match(/<.+>/)[0]); // "<div>content</div>"
// Lazy - matches as little as possible
console.log(html.match(/<.+?>/)[0]); // "<div>"
Anchors and Boundaries
| Pattern | Matches |
|---|---|
^ |
Start of string (or line with m flag) |
$ |
End of string (or line with m flag) |
\b |
Word boundary |
\B |
Non-word boundary |
/^hello/.test("hello world"); // true (starts with hello)
/world$/.test("hello world"); // true (ends with world)
/^hello$/.test("hello"); // true (exactly "hello")
/\bcat\b/.test("the cat sat"); // true (whole word)
/\bcat\b/.test("category"); // false (not a whole word)