JavaScript regex is not PCRE
Sumit Jha · Updated 2026-11-06
A JavaScript regular expression is what RegExp does in that browser, which is the same family Node uses. Flags change matching: g finds more than one, i folds case, m changes anchors, s lets dot match newlines, u and v change Unicode handling. A pattern copied from PCRE can fail or, worse, match a different span.
Flags that change the result
Without g, exec and match stop at the first hit, and lastIndex behavior differs once g is on. i is Unicode-aware only when u or v is set, so case folding of some letters will surprise you. m makes ^ and $ match line boundaries, not only the whole string. s makes . match \n. Forgetting s is the usual reason a multi-line snippet “does not match.”
Named groups (?<name>…) are available in modern engines. Numbered groups still count. Group 0 is the whole match. A visualizer shows the structure. The tester shows what the engine actually captured on your sample.
What does not carry over
Recursive patterns, some possessive quantifiers, and a few lookaround forms that PCRE accepts are syntax errors in JavaScript, or they mean a different thing. \d is not “ASCII digits only” once Unicode mode is on. Test the pattern in the engine that will run it in production. If production is Node, this tester is the right family. If production is Postgres or Python, it is only a sketch.
Catastrophic backtracking is still possible. Nested quantifiers on overlapping text can freeze the tab. Shorten the sample and simplify the quantifier. A debugger steps through a small input. It cannot make an exponential pattern safe.
A practical loop
Write the pattern, include one line that must match and one that must not, and read the groups. If nothing matches, step in the debugger before you add more optional clauses. If the shape is the confusing part, look at the graph, then come back to the tester. The graph is not a match result.
One pattern, three flags
Take the pattern ^error: (.+)$ and the text “error: disk full” on one line and “ERROR: disk full” on the next, with a blank line between them. Without flags, only the first line matches, and only if it starts the string. Add i and the second line’s letters match, but ^ still means the start of the whole text, so a leading newline can hide the hit. Add m and each line is a candidate. Add s only if you expected the dot to cross a newline, which this pattern does not need.
Read group 1, not the whole match, when you want the message after the colon. Group 0 is the entire match, including the “error: ” prefix. Named groups make that harder to mix up, and they are fine in current browsers and Node. If you copy a Python (?P<name>…) group, JavaScript will throw. Rewrite it as (?<name>…).
If the tester hangs, you have nested quantifiers and an input that forces the engine to retry. Shorten the sample to a few characters and replace .+ with something that cannot overlap, then put the longer sample back. The debugger is for a pattern that fails. It is not a way to wait out a bad one. Production should use the same flags you settled on here, written next to the literal, not implied by an editor setting.
Unicode is the other silent flag. Without u, \w and ranges follow an older definition and some escapes are syntax errors or, worse, match one UTF-16 code unit of a character that needs two. Emoji and some letters will split. Turn u on when the text is real user input, and retest the groups, because the same pattern can capture a different span. The visualizer shows the expression you typed. It does not show what a PCRE server would do with it. If the code runs in the browser or in Node, the tester is the authority. If it runs in Postgres, take the pattern home and run it there.
FAQ
Which flavor does DevTooKit use?
JavaScript, via the browser RegExp implementation. That matches Node, not PCRE or POSIX.
Why does the same pattern work in my editor?
Editor search is often a different engine. Re-test in the runtime that will execute the code.
Related tools
- Regex DebuggerStep-by-step breakdown of how a regex matches: capture groups, named groups, lookahead/lookbehind.
- Regex VisualizerVisualize a regex as a Thompson NFA state machine graph. See states, transitions, and epsilon moves.
Limitation: this note describes the DevTooKit tool and the general rule behind it. Production libraries, clocks, and schedulers can differ. Check those docs before you ship.