DevLab
.*
Regex⭐ Popularbeginner

Regex Tester

test and debug regular expressions with real-time matching

By Bikram NathLast updated

A regex tester runs your pattern against sample text in real time and highlights every match, group, and capture as you type. Paste a log line like `2024-01-15 ERROR [db] connection timeout` and a pattern like `(\w+) (\w+) \[(\w+)\]` to instantly see three numbered capture groups light up. Unlike regex101, the matching here uses the JavaScript engine directly, so what you see is exactly what `String.prototype.matchAll()` returns in your browser.

Try it now — free, instant, no signup

What is Regex Tester?

A regex tester takes a pattern and a block of sample text and shows you every match in real time, including which capture groups captured what. Type `(\d{4})-(\d{2})-(\d{2})` against a CSV of timestamps and each date component snaps into its own highlighted group immediately, no page reload required.

Developers typically reach for regex101 when they need multi-engine support (PCRE, Python, Go) or detailed step-by-step debugger output showing each state the engine visited. This tool targets the opposite case: you already know the regex will run in JavaScript and you want instant feedback in the same engine, with group highlighting, without switching context.

The practical gotcha is that JavaScript's `RegExp` has no possessive quantifiers and no atomic groups, so patterns that work in PCRE or Python's `re` module can silently change behavior or throw a `SyntaxError` here. ECMAScript 2018 added lookbehind assertions (`(?<=...)` and `(?<!...)`), but older V8 builds and all current Safari versions before 16.4 reject them at parse time, which this tester will surface immediately as a match error rather than a silent miss.

When to use Regex Tester

Verify a capture group extracts exactly the right substring before wiring it into a `String.prototype.match()` call in production code.
Diagnose why a log-parsing pattern grabs an extra trailing space or newline by watching group 1 highlight in real time.
Confirm that a form-validation regex correctly rejects edge cases like `user@@example.com` or an empty local part before shipping the rule.

Frequently Asked Questions

Why does my pattern match across lines when I didn't intend it to?
By default, `.` in JavaScript regex does not match newline characters (`\n`, `\r`). If your matches are spanning lines anyway, you have likely enabled the `s` (dotAll) flag, introduced in ECMAScript 2018, which makes `.` match every character including newlines. Check which flags are active. If you want `.` to stop at line boundaries, remove the `s` flag. If you want `^` and `$` to anchor to each line rather than the whole string, add the `m` (multiline) flag instead.
Does this tester support named capture groups?
Yes. Named capture groups using the `(?<name>...)` syntax were standardized in ECMAScript 2018 and are supported in every major browser engine released after mid-2018. In the match output, named groups appear alongside their numeric index. Use `match.groups.name` to access them in code. One practical note: duplicate group names are not allowed in JavaScript regex, unlike in PCRE where you can reuse a name in alternation branches, so a pattern like `(?<y>\d{4})|(?<y>\d{2})` will throw a `SyntaxError` here.
Why does adding the global flag change how my regex matches?
The `g` flag makes `RegExp` stateful. A `RegExp` object with `g` set maintains a `lastIndex` property, and repeated calls to `.exec()` or `.test()` advance from that position rather than restarting. In this tester that means you see all non-overlapping matches across the full input, which is usually what you want. But if you copy the pattern into code and call `.test()` in a loop on the same compiled `RegExp` instance without resetting `lastIndex`, it will alternately return `true` and `false` on identical strings, a classic JavaScript footgun.
How does this handle Unicode, and do I need the u flag?
Without the `u` flag, JavaScript regex operates on UTF-16 code units, not Unicode code points. Emoji and characters outside the Basic Multilingual Plane are stored as surrogate pairs, so `.` matches only half a character and `\w` misses non-ASCII letters entirely. Adding the `u` flag switches to full Unicode mode: `.` covers an entire code point, `\u{1F600}` notation works, and the engine validates your pattern more strictly, throwing on things like unmatched `{` that are silently ignored without `u`. For any text that might contain emoji or non-Latin scripts, `u` is the correct default.
My pattern works here but fails in Node.js. What could cause that?
The most common cause is a V8 version mismatch. Features like lookbehind assertions (`(?<=...)`) and the `d` flag (indices for substring matches, ECMAScript 2022) shipped in V8 at specific versions. If your Node.js is older than 16 for lookbehinds or older than 18 for the `d` flag, patterns that parse fine in a current browser will throw `SyntaxError` at runtime. Run `node -e "console.log(process.versions.v8)"` to confirm your engine version, then cross-reference it against the ECMAScript compatibility table for the feature you are using.

Related Tools