← thecodex.expert · The Codex Family of Knowledge
The Codex / JavaScript / Regular Expressions

Regular Expressions

Pattern matching in JavaScript — the syntax, the flags, named groups, and the string methods that use them.

What it is, in plain English: A regular expression (regex) is a pattern that describes a set of strings. You use it to test whether a string matches a pattern, to find matches inside a string, or to replace parts of a string. Regex looks intimidating at first — it's dense and symbol-heavy. But once you learn a handful of building blocks, you can describe almost any text pattern. JavaScript has regex built in — no imports needed.
Where this bites you

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"));          // false

Slash 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/)           // 6

Capturing 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"
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.