← All concepts
Beyond the Course

Regular Expressions

A pattern language for finding, testing, and pulling pieces out of text.

Definition

A regular expression, or regex, is a pattern that describes a shape of text. You write one as a literal between slashes, like /\d+/, or by constructing a `new RegExp("\\d+")`, and pair it with methods such as `RegExp.prototype.test`, `String.prototype.match`, `String.prototype.matchAll`, and `String.prototype.replace` to check, extract, or rewrite text that fits the pattern. Parentheses inside a pattern create a capture group: `(\d{3})-(\d{4})` matches a run of three digits, a dash, and a run of four digits, while also remembering what each parenthesized part matched so you can read it back afterward, as `match[1]` and `match[2]`, or as `$1` and `$2` inside a replacement string. Flags placed after the closing slash change how the pattern is applied: `g` (global) finds every match in the string instead of stopping at the first one, and `i` (ignore case) makes letters match regardless of case. Without the `g` flag, methods like `match` return only the first match along with its capture groups; with it, they return every matched substring but drop the group detail, which is why `matchAll` exists for getting every match's groups at once.

Examples

/\d/.test("room A12"); // true
/^\d+$/.test("room A12"); // false

The first pattern only asks whether a digit appears anywhere. Anchoring with ^ and $ requires the entire string to be digits, which "room A12" is not.

const re = /(\d{3})-(\d{4})/;
const match = "call 555-1234".match(re);
match[0]; // "555-1234"
match[1]; // "555"
match[2]; // "1234"

match[0] is the whole matched substring; match[1] and match[2] are what each parenthesized capture group matched, in order.

"2024-01-15".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1");
// "15/01/2024"

$1, $2, and $3 in the replacement string refer back to the three capture groups, letting the date be reordered without hardcoding its parts.

Common mistakes

  • Forgetting the g flag and being surprised that match or replace only touches the first occurrence instead of every one in the string.
  • Assuming match always returns capture groups; without the g flag it does, but with g it returns every matched substring and drops the group detail, so matchAll is needed for that.
  • Writing a pattern without anchors (^ and $) and expecting it to require the whole string to match, when it actually matches if the pattern appears anywhere.

Key takeaways

  • Parentheses create a capture group, letting you pull out a specific piece of what matched.
  • The g flag finds every match in a string instead of stopping at the first.
  • The i flag makes the match ignore letter case.
  • test checks for a match, match and matchAll extract matches, and replace rewrites text using the pattern.
Check your understanding

"cat, Cat, CAT".match(/cat/gi) returns what?

Where you see this

  • Validating the shape of user input, like checking a string looks like an email address or a phone number.
  • Extracting structured pieces out of unstructured text, such as pulling numbers or dates out of a log line.
  • Search-and-replace across text, including reformatting captured groups into a different order.
  • Splitting or tokenizing a string on something more flexible than a fixed character, like runs of whitespace.

Practice this

Further reading

Previous
Immutable Update Patterns
Next
Iterators and Generators