Skip to Content
Built InsRegExp

RegExp

The built-in for pattern matching in strings. Define a pattern, then test, match, or replace text with it.

When to use it

  • Validation — check if a string matches a format (email, phone, URL)
  • Extraction — pull structured data out of text (dates, IDs, tokens)
  • Search and replace — transform strings with patterns
  • Splitting — break a string apart on a complex delimiter

Anatomy

const re = /pattern/flags // literal syntax const re2 = new RegExp('pattern', 'flags') // constructor (dynamic patterns) // flags /g/ // global — find all matches, not just the first /i/ // case-insensitive /m/ // multiline — ^ and $ match line boundaries /s/ // dotAll — . matches newlines too /u/ // unicode — correct handling of surrogate pairs // methods re.test('string') // true/false — does it match? 'string'.match(re) // array of matches or null 'string'.matchAll(re) // iterator of all matches with groups (needs /g) 'string'.replace(re, 'new') // replace matches 'string'.search(re) // index of first match or -1 'string'.split(re) // split on pattern

At a glance

MethodWhat it does
re.test(str)Boolean — does the string match?
str.match(re)First match (or all with /g)
str.matchAll(re)Iterator of all matches with capture groups
str.replace(re, new)Replace matches
str.replaceAll(re, new)Replace all (requires /g flag)
str.search(re)Index of first match
str.split(re)Split string on pattern

Common patterns

PatternWhat it matches
.Any character (except newline)
\dDigit (0-9)
\wWord character (letter, digit, underscore)
\sWhitespace (space, tab, newline)
^ / $Start / end of string
* / + / ?0+, 1+, 0 or 1 repetitions
{n} / {n,m}Exactly n / between n and m repetitions
[abc]Character class — a, b, or c
[^abc]Negated class — not a, b, or c
(group)Capture group
(?:group)Non-capturing group
(?<name>group)Named capture group

1. Simple — test a pattern

const emailish = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ // ^ — start of string // [^\s@]+ — one or more chars that aren't whitespace or @ // @ — literal @ // [^\s@]+ — domain name // \. — literal dot // [^\s@]+$ — TLD through end of string emailish.test('alice@test.com') // true emailish.test('not an email') // false

2. Intermediate — named capture groups

const datePattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ const match = '2026-03-15'.match(datePattern) match.groups.year // '2026' match.groups.month // '03' match.groups.day // '15'

3. Advanced — replace with a function

// convert markdown bold to HTML const md = 'This is **bold** and **important**' const html = md.replace(/\*\*(.+?)\*\*/g, (fullMatch, content) => { // fullMatch = '**bold**' // content = 'bold' (first capture group) return `<strong>${content}</strong>` }) // 'This is <strong>bold</strong> and <strong>important</strong>'

Gotchas

Forgetting the global flag

'aaa'.match(/a/) // ['a'] — only the first match 'aaa'.match(/a/g) // ['a', 'a', 'a'] — all matches // matchAll always requires /g 'aaa'.matchAll(/a/) // TypeError: must be called with a global RegExp

Stateful global regexes

const re = /a/g re.test('abc') // true — lastIndex moves to 1 re.test('abc') // false — starts searching from index 1, finds nothing re.test('abc') // true — lastIndex reset to 0 after a failed match // each .test() or .exec() on a /g regex advances lastIndex // create a new regex or use string methods to avoid this

  • .filter() — filter arrays with regex: arr.filter(s => /pattern/.test(s))
  • .map() — transform strings with regex: arr.map(s => s.replace(/pattern/, 'new'))
Last updated on