JSON in JavaScript

A regular expression (regex) is a pattern that describes a set of strings. You use it to search for text, check if a value matches a certain format, or replace parts of a string.

Think of it like a search filter. Instead of searching for one exact word, you describe a shape of text — "a string that starts with a digit, followed by three letters, ending in @". Regex lets you express that shape in a compact notation.

You create a regex in JavaScript in two ways:

javascript

// 1. Regex literal — the most common way
const pattern = /hello/;

// 2. RegExp constructor — useful when the pattern is dynamic
const word = "hello";
const pattern2 = new RegExp(word);

// Test a string against the pattern
console.log(pattern.test("say hello there")); // true
console.log(pattern.test("goodbye"));         // false

Regex is not just a JavaScript thing — it exists in almost every programming language. Once you understand it here, the core ideas carry over everywhere.

A regex literal is written between two forward slashes: /pattern/. After the closing slash you can add flags like g, i, or m to change how the match works.

javascript

// Pattern: match the word "cat" (case-sensitive)
const pattern = /cat/;
console.log(pattern.test("The cat sat"));  // true
console.log(pattern.test("The Cat sat"));  // false — uppercase C

// With the i flag: case-insensitive
const patternI = /cat/i;
console.log(patternI.test("The Cat sat")); // true

Special characters in regex have reserved meanings. If you want to match a literal ., *, +, ?, (, ), [, {, \, ^, $, or |, you must escape them with a backslash:

javascript

// . without escape matches ANY character
/c.t/.test("c@t"); // true — . matches @

// \. matches a literal dot
/c\.t/.test("c.t"); // true
/c\.t/.test("c@t"); // false

Character classes let you match one character from a set. You define a class with square brackets [...].

  • [abc] — matches a, b, or c
  • [^abc] — matches any character that is not a, b, or c
  • [a-z] — any lowercase letter
  • [A-Z] — any uppercase letter
  • [0-9] — any digit
  • [a-zA-Z0-9] — any letter or digit

There are also built-in shorthand classes:

  • \d — any digit (same as [0-9])
  • \D — any non-digit
  • \w — any word character: letters, digits, underscore (same as [a-zA-Z0-9_])
  • \W — any non-word character
  • \s — any whitespace (space, tab, newline)
  • \S — any non-whitespace
  • . — any character except newline

javascript

console.log(/\d/.test("abc3"));    // true — contains a digit
console.log(/\d/.test("abcdef"));  // false — no digits
console.log(/\w/.test("hello_1")); // true
console.log(/\s/.test("hi there")); // true — has a space
console.log(/[aeiou]/.test("sky")); // false — no vowels

Quantifiers control how many times a character or group must appear to count as a match.

  • * — 0 or more times
  • + — 1 or more times
  • ? — 0 or 1 time (makes it optional)
  • {n} — exactly n times
  • {n,} — at least n times
  • {n,m} — between n and m times

javascript

// + means one or more digits
console.log(/\d+/.test("abc123")); // true
console.log(/\d+/.test("abcdef")); // false

// {3} means exactly 3 digits
console.log(/\d{3}/.test("12"));   // false
console.log(/\d{3}/.test("123"));  // true
console.log(/\d{3}/.test("1234")); // true — "123" matches inside it

// ? makes the 's' optional
console.log(/colou?r/.test("color"));  // true
console.log(/colou?r/.test("colour")); // true

By default, quantifiers are greedy — they match as much as possible. Add ? after a quantifier to make it lazy (match as little as possible):

javascript

const str = "bold and more";

// Greedy: matches as much as possible
const greedy = str.match(/.*<\/b>/);
console.log(greedy[0]); // bold and more  (too much)

// Lazy: matches as little as possible
const lazy = str.match(/.*?<\/b>/);
console.log(lazy[0]);   // bold  (just the first)

Anchors do not match characters. They match a position in the string. This lets you say "this pattern must appear at the start" or "must appear at the end".

  • ^ — matches the start of the string
  • $ — matches the end of the string
  • \b — matches a word boundary (between a word character and a non-word character)
  • \B — matches a non-word boundary

javascript

// ^ anchors to the start
console.log(/^Hello/.test("Hello world")); // true
console.log(/^Hello/.test("Say Hello"));   // false

// $ anchors to the end
console.log(/world$/.test("Hello world")); // true
console.log(/world$/.test("world peace")); // false

// ^ and $ together: exact full-string match
console.log(/^\d{5}$/.test("12345"));  // true — exactly 5 digits
console.log(/^\d{5}$/.test("1234"));   // false
console.log(/^\d{5}$/.test("123456")); // false

// \b word boundary
console.log(/\bcat\b/.test("the cat sat"));   // true
console.log(/\bcat\b/.test("concatenate"));   // false

Parentheses (...) create a capturing group. They let you apply a quantifier to a whole sub-pattern, and also capture the matched text so you can use it later.

javascript

// Group with quantifier: (ab)+ means "ab" repeated one or more times
console.log(/(ab)+/.test("ababab")); // true
console.log(/(ab)+/.test("aab"));    // false

// Capture groups in match()
const date = "2026-04-06";
const match = date.match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(match[0]); // "2026-04-06" — full match
console.log(match[1]); // "2026"        — group 1
console.log(match[2]); // "04"          — group 2
console.log(match[3]); // "06"          — group 3

Use (?:...) for a non-capturing group when you need grouping for a quantifier but don't need to capture the value:

javascript

// (?:ab)+ groups but does not capture
const m = "ababab".match(/(?:ab)+/);
console.log(m[0]); // "ababab" — full match
console.log(m[1]); // undefined — no capture group

You can also use the | (pipe) character as an OR operator inside or outside a group:

javascript

// Match "cat" or "dog"
console.log(/cat|dog/.test("I have a dog")); // true
console.log(/cat|dog/.test("I have a fish")); // false

// Group the OR to apply a quantifier
console.log(/(cat|dog)s?/.test("cats")); // true
console.log(/(cat|dog)s?/.test("dogs")); // true

Flags go after the closing slash and change how matching works. You can combine multiple flags.

  • i — case-insensitive matching
  • gglobal: find all matches, not just the first
  • mmultiline: ^ and $ match start/end of each line, not the whole string
  • s — dot-all: . matches newlines too
  • u — Unicode mode
  • d — return start/end indices for each match (ES2022)

javascript

// i flag — case-insensitive
console.log(/hello/i.test("HELLO WORLD")); // true

// g flag — find all matches
const str = "cat bat sat";
const all = str.match(/[a-z]at/g);
console.log(all); // ["cat", "bat", "sat"]

// Without g — only the first match
const first = str.match(/[a-z]at/);
console.log(first[0]); // "cat"

// m flag — multiline
const multi = "line1\nline2\nline3";
const lines = multi.match(/^\w+/gm);
console.log(lines); // ["line1", "line2", "line3"]

You can use regex with both RegExp methods and String methods.

RegExp methods:

  • regex.test(str) — returns true or false
  • regex.exec(str) — returns match array with index info, or null

javascript

const regex = /\d+/;
console.log(regex.test("abc 123"));  // true
console.log(regex.test("no nums"));  // false

const result = regex.exec("abc 123 def");
console.log(result[0]); // "123"
console.log(result.index); // 4 — position in string

String methods that accept regex:

  • str.match(regex) — returns array of matches (or null)
  • str.matchAll(regex) — returns iterator of all matches with details (requires g flag)
  • str.search(regex) — returns index of first match, or -1
  • str.replace(regex, replacement) — replaces match with a string or function
  • str.replaceAll(regex, replacement) — replaces all matches (requires g flag)
  • str.split(regex) — splits string at each match

javascript

const str = "Hello World 2026";

// match — returns array
console.log(str.match(/\d+/));       // ["2026", index: 12, ...]
console.log(str.match(/\d+/g));      // ["2026"]

// search — returns index
console.log(str.search(/World/));    // 6
console.log(str.search(/xyz/));      // -1

// replace — swap matched text
console.log(str.replace(/World/, "JavaScript")); // "Hello JavaScript 2026"

// replace with a function
const result = "cat and dog".replace(/cat|dog/g, match => match.toUpperCase());
console.log(result); // "CAT and DOG"

// split on whitespace
console.log("one  two   three".split(/\s+/)); // ["one", "two", "three"]
Practical use case: Validate an email address format — /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email). This is a basic check, not a perfect validator, but it covers most real-world cases.
  • A regular expression is a pattern that matches text. Create one with a literal /pattern/ or new RegExp("pattern").
  • Character classes: [abc] matches one of those chars. Shorthands: \d (digit), \w (word char), \s (whitespace).
  • Quantifiers: * (0+), + (1+), ? (0 or 1), {n,m} (range). Add ? after one to make it lazy.
  • Anchors: ^ = start, $ = end. Together they force an exact full-string match. \b = word boundary.
  • Groups: (abc) captures. (?:abc) groups without capturing. | = OR.
  • Flags: i = case-insensitive, g = find all matches, m = multiline anchors.
  • Key methods: regex.test() (boolean), str.match() (array), str.replace() (new string), str.split() (array).
  • Quantifiers are greedy by default — they match as much as possible. Append ? to make them lazy.
What's next? Head over to the Error Handling tutorial to learn how to catch and handle errors in JavaScript.
  • What is a regular expression and what is it used for?
  • What is the difference between creating a regex with a literal vs new RegExp()?
  • What does the g flag do in a regular expression?
  • What is the difference between + and * quantifiers?
  • What is the difference between ^ inside square brackets and ^ outside?
  • What is a capturing group and how do you access captured text?
  • What is the difference between a greedy and a lazy quantifier?
  • How would you check if a string contains only digits?
  • How would you replace all occurrences of a word in a string using regex?
  • What does \b match in a regular expression?