Regex Tester
Test JavaScript regular expressions against sample input with live match highlighting
How to Regex Tester Online
Test JavaScript regular expressions against real input with live match highlighting and capture-group breakdown.
- Type your pattern into the slash-delimited input. Standard JavaScript regex syntax — no need to wrap in slashes manually.
- Toggle flags using the buttons below the pattern, or type them into the flags box. Hover any flag to see what it does.
- Paste your test string into the larger textarea. Matches highlight as you type — there is no Run button.
- Scan the highlighted view for what matched. Hover any highlighted segment to see its match number.
- Below the highlighted view, the matches list shows each match with its position and any capture groups (both numbered `$1`, `$2` and named `?<name>`).
- If your pattern is invalid, the error message comes straight from the browser's `new RegExp()` constructor — same wording you would see in DevTools.
About Regex Tester
Regular expressions are the smallest, most-used DSL in computing. Search-replace dialogs, log filters, web framework routers, validation rules, syntax highlighters, and every "extract phone numbers from text" task on the planet uses them. They are also famously hard to debug: a missing backslash silently changes meaning, a greedy quantifier eats more than you wanted, and a small mistake in a lookbehind makes the pattern silently match the wrong thing. The fix is not memorizing the syntax — it is testing patterns interactively against the exact input you care about, so you see at a glance what matches and what does not.
The tester uses the **ECMAScript regex engine** built into your browser. That is the same engine that runs in Chrome, Firefox, Safari, Node.js, Bun, and Deno, so a pattern you tune here will behave identically in your application code. Most of the standard regex features are supported: character classes, quantifiers, anchors, alternation, capturing and non-capturing groups, backreferences (`\1`, `\2`), lookaheads (`(?=…)`), lookbehinds (`(?<=…)`), named captures (`(?<name>…)`), and Unicode property escapes (`\p{L}`, `\p{Script=Hangul}`) when the `u` flag is enabled. Features that exist only in PCRE — recursive patterns, possessive quantifiers, the `\K` reset, conditional patterns — do not work because JavaScript itself does not implement them.
Flags matter more than people remember. `g` makes the regex global, scanning past the first match; without it, `String.prototype.match` returns only the first occurrence and `replace` only swaps the first instance. `i` is case-insensitive. `m` makes `^` and `$` match line boundaries rather than the start and end of the whole string — important whenever you are parsing input with newlines. `s` ("dotall") lets `.` match newlines, which is useful for matching across blocks of text. `u` switches the engine into Unicode mode, which both fixes surrogate-pair handling for emoji and astral characters AND unlocks property escapes like `\p{L}` for "any letter in any script." `y` ("sticky") forces matching from `lastIndex` only, which most application code never needs but tokenizers and parsers rely on.
The match list below the highlight view shows three pieces of information per match: the literal string that matched, the zero-based starting index, and every capture group's content. **Numbered groups** (`(\w+)` is `$1`) and **named groups** (`(?<name>\w+)` is `m.groups.name`) are listed separately even though they refer to the same content — because real-world code reads them via different APIs and seeing both lets you confirm your extraction logic. Undefined groups (a group that exists in the pattern but did not participate in the match, common with alternation like `(foo)|(bar)`) are explicitly shown rather than silently omitted.
Three practical hazards the tester surfaces. **Zero-width matches** — patterns like `/(?=\d)/g` that match a position rather than characters — naively loop forever in JavaScript. The tester advances one character past every zero-width match, matching how Chrome's DevTools, Node's REPL, and TC39's spec algorithm handle it. **Match explosion** — a pattern like `/./g` against a megabyte of text would render millions of `<mark>` elements and freeze the page; the tester caps at 5,000 matches and reports it. **Invalid patterns** — syntax errors come straight from the browser's `new RegExp()` constructor, so the error message is exactly what you would see in DevTools when the pattern reaches production.
Everything runs in your browser. The pattern is compiled by the browser's regex engine. No network requests, no logging. Patterns containing sensitive data (internal hostnames, employee emails, API keys you are validating) never leave your tab.
Related Tools
Frequently Asked Questions
Which regex flavor does this tester use?
ECMAScript / JavaScript regex — the same engine your browser ships. That means lookaheads (`(?=…)`), lookbehinds (`(?<=…)`), named groups (`(?<name>…)`), and Unicode property escapes (`\p{L}` with the `u` flag) all work. PCRE-only features like recursive patterns, possessive quantifiers, and `\K` do not. If you are testing a pattern that will run in Node, Bun, Deno, or any browser, this is the same engine.
Why is the `g` flag required for multi-match output?
Without `g`, JavaScript regex matches only the first occurrence — that is how the language is specified. The tester auto-applies `g` internally so it can iterate matches via `matchAll`, but it shows you the flags exactly as you typed them so the pattern matches what your code would do. If you forget `g` in production code, you will get only the first match silently.
What is the difference between `(?:…)` and `(…)`?
`(…)` is a capturing group — its content becomes `m[1]`, `m[2]`, etc. and is reported in the match list below. `(?:…)` is a non-capturing group — it groups for the regex engine but does not occupy a slot in the result. Use non-capturing groups for alternation and quantifiers when you do not need the value back, since they are slightly faster and keep the capture-group indices clean.
Why does my zero-width pattern not loop forever?
ECMAScript regex with the `g` flag is supposed to loop infinitely on zero-width matches like `/(?=\d)/g` if implemented naively. The tester detects a zero-width match and advances one character manually, just like Chrome's DevTools and Node REPL do internally. This means lookaheads-only patterns produce a finite list of positions.
Why are named captures shown separately from numbered groups?
A pattern like `(?<area>\d{3})-(?<num>\d{4})` produces both — the area code is in `m[1]` AND `m.groups.area`. The tester shows both views because some code paths read numbered groups (`m[1]`) and others read named ones (`m.groups.area`). Seeing both lets you confirm you are extracting via the right path.
What happens if my pattern matches too many times?
The tester caps iteration at 5,000 matches and shows an error if you go over. This is a safety net against patterns like `/./g` against multi-megabyte input, which would lock up the page rendering 5 million `<mark>` elements. Narrow the input or the pattern.
Is my pattern or input sent to a server?
No. The regex engine is `new RegExp()` running in your browser tab. The page makes no network requests during testing. You can verify in your browser DevTools.