Regex tester · Guide

Test Regex JavaScript: Patterns in the Browser and Node

JavaScript regex is straightforward until the global flag gets involved. Then a regex object starts carrying state between calls, and code that looks correct returns alternating true and false.

The lastIndex trap

A regex with g or y remembers where it stopped. Reusing the same object across calls resumes from there:

JavaScript
const re = /\d+/g;
re.test('123');   // true
re.test('123');   // false  ← lastIndex is now 3
re.test('123');   // true   ← reset after failure

// fixes: drop the g flag, or create the regex per call
const check = (s) => /\d+/.test(s);

This is the single most reported JavaScript regex bug. If a validation function works every other time, lastIndex is why.

match, matchAll and exec

str.match(re) without g returns a match object with capture groups; with g it returns an array of full matches only, discarding the groups. That silent change catches people out.

str.matchAll(re) requires g and yields full match objects with groups and indices — it is what you usually want:

JavaScript
for (const m of '2026-08 2027-01'.matchAll(/(?<y>\d{4})-(?<mo>\d{2})/g)) {
  console.log(m.groups.y, m.groups.mo, m.index);
}

Modern flags

s (dotall) since ES2018 lets . cross newlines. u enables proper Unicode handling, and v (ES2024) adds set operations inside character classes.

d (ES2022) adds indices to match results, giving the start and end of each group — useful for highlighting.

Without u, . and quantifiers operate on UTF-16 code units, so an emoji counts as two characters and a character class can split it. Add u whenever the input may contain non-BMP characters.

Replacement

replaceAll needs a g flag if given a regex, and throws otherwise. In replacement strings, $1 and $<name> insert groups, and $$ is a literal dollar.

A function replacement is clearer than a dense pattern when the transformation has conditions — it receives the match, the groups and the offset.

Frequently asked questions

Why does test() alternate between true and false?

The g flag makes the regex stateful via lastIndex. Remove g, or create a new regex per call.

Why did my capture groups disappear?

String.match with the g flag returns only full matches. Use matchAll or exec in a loop.

When do I need the u flag?

Whenever the input can contain emoji or other non-BMP characters, so the engine works on code points rather than UTF-16 units.

Ready to try it?

Open the free browser-based Regex tester and apply what you just read — no sign-up, runs locally.

Open the Regex tester tool