Regular Expressions
Pattern matching in JavaScript — the syntax, the flags, named groups, and the string methods that use them.
When the pattern comes from a variable, such as a search box, new RegExp(text) reads that text as regex syntax, not as plain characters. A user searching for 1.5 gets every price where any character sits between a 1 and a 5, because . means "any character". Input such as c++ is worse: it isn't a valid pattern at all, and the constructor throws SyntaxError: Invalid regular expression: /c++/: Nothing to repeat.
const prices = ["1.5", "105", "125"];
const search = "1.5"; // typed by the user
const re = new RegExp(search);
console.log(prices.filter(p => re.test(p)));
// [ '1.5', '105', '125' ]Pattern matching — finding and working with text patterns
A regular expression describes a pattern in text. Instead of checking if a string equals "hello", you can check if it contains an email address, starts with a number, or matches a date format. Regex is dense to read but logical once you learn the building blocks.
Writing a regex
// Slash notation — the most common:
const pattern = /hello/; // pattern that matches the literal text "hello"
// test() — does the string contain this pattern?
console.log(/hello/.test("say hello there")); // true
console.log(/hello/.test("goodbye")); // falseSlash notation, as above, is for patterns you write into the code. To build a pattern from text at runtime, use the RegExp constructor, and escape the text first so every special character is matched literally. The helper below is the escaping function given in MDN's regular expressions guide. (A built-in RegExp.escape() has since been added to the language, but Node 22 doesn't have it, so check your runtime before relying on it.)
const prices = ["1.5", "105", "125"];
const search = "1.5";
const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const re = new RegExp(escapeRegExp(search));
console.log(prices.filter(p => re.test(p)));
// [ '1.5' ]The essential building blocks
// Literal characters — match exactly:
/cat/ // matches "cat" anywhere in the string
// . (dot) — any single character except newline:
/c.t/ // matches "cat", "cut", "c3t", "c t" — any character in the middle
// Character classes [] — one of these characters:
/[aeiou]/ // any vowel
/[a-z]/ // any lowercase letter
/[0-9]/ // any digit (same as \d)
/[^aeiou]/ // NOT a vowel (^ inside [] means "not")
// Shorthand character classes:
// \d = [0-9] digit
// \w = [a-zA-Z0-9_] word character (letter, digit, underscore)
// \s = whitespace (space, tab, newline)
// \D, \W, \S = the OPPOSITES (non-digit, non-word, non-space)
// Quantifiers — how many times:
/a*/ // 0 or more a's
/a+/ // 1 or more a's
/a?/ // 0 or 1 a (optional)
/a{3}/ // exactly 3 a's
/a{2,4}/ // 2 to 4 a's
// Anchors — position, not characters:
/^hello/ // "hello" at the START of the string
/world$/ // "world" at the END of the string
/hello/ // "hello" as a whole word (word boundary)Flags — modifying how the pattern behaves
const text = "Hello World HELLO world";
/hello/.test(text) // false — case-sensitive by default
/hello/i.test(text) // true — i flag: case-insensitive
text.match(/hello/i) // ["Hello"] — first match only
text.match(/hello/gi) // ["Hello", "HELLO", "hello"] — g flag: find all matches
// Common flags:
// i — case-insensitive
// g — global (find ALL matches, not just first)
// m — multiline (^ and $ match line start/end, not just string start/end)
// s — dotAll (. matches newlines too)
// u — unicode (full unicode support)Using regex with string methods
const text = "The price is $12.99 and was $15.00";
// match() — find matches:
text.match(/\$[\d.]+/g) // ["$12.99", "$15.00"]
text.match(/\$[\d.]+/) // ["$12.99"] — first only (no g flag)
// test() — boolean check:
/^\d{4}-\d{2}-\d{2}$/.test("2026-06-27") // true — looks like an ISO date
/^\d{4}-\d{2}-\d{2}$/.test("27-06-2026") // false — wrong order
// replace() — substitute matched text:
"hello world".replace(/\s+/g, " ") // "hello world" — collapse spaces
"2026-06-27".replace(/-/g, "/") // "2026/06/27" — swap delimiters
// split() — split on a pattern:
"one two three".split(/\s+/) // ["one", "two", "three"]
// search() — index of first match, or -1:
"hello world".search(/world/) // 6Capturing groups — extract parts of a match
// Parentheses create a capturing group:
const date = "2026-06-27";
const match = date.match(/(\d{4})-(\d{2})-(\d{2})/);
if (match) {
console.log(match[0]); // "2026-06-27" — full match
console.log(match[1]); // "2026" — first group
console.log(match[2]); // "06" — second group
console.log(match[3]); // "27" — third group
}
// Named groups — much clearer:
const named = date.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
console.log(named.groups.year); // "2026"
console.log(named.groups.month); // "06"
console.log(named.groups.day); // "27"Official Sources
- MDN Web Docs — Regular expressions
- MDN Web Docs — RegExp
- ECMAScript 2024 — RegExp (§22.2)
- MDN Web Docs — String.prototype.matchAll()
The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.