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:
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:
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