Regex Tester
Max 1 MB · Matches automatically as you type
Processed entirely in your browser — nothing is sent to a server.
A regular expression (regex) is a pattern for matching text — a compact, if famously terse, way to say “find every substring that looks like this” without writing a hand-rolled parser for it. This tool runs a pattern against sample text live as you type, highlights every match directly in the text, and breaks out capture groups individually below it, so you can see exactly what a pattern does before dropping it into real code.
Matching runs entirely in your browser using JavaScript’s own native RegExp engine — the same one your browser already runs when a <script> on any page uses a regex, and the same one Node.js uses server-side. No separate regex library, no server round-trip: what you see here is exactly what pattern.test(text) or text.match(pattern) would do in real code.
Flags change how a pattern matches, not what it looks like: g finds every match instead of stopping at the first, i ignores case, m makes ^/$ anchor to each line instead of the whole string, s lets . match newlines too, and u treats the pattern as full Unicode code points rather than raw UTF-16 units. Each is a plain checkbox — toggle any combination and the results update automatically.
Capture groups — the parenthesized parts of a pattern — are extracted individually for every match, both named ((?<year>...)) and positional. A full match gets a solid underline in the preview; a capture group inside it gets a dashed underline in a different color, so the two are told apart by shape as well as color, not color alone. The breakdown list below shows each group’s exact text and whether it participated at all, since a group inside an unmatched alternation branch simply doesn’t.
A pattern that never finishes is a real, inherent risk with any regex tool that runs in your own browser rather than on a server with a hard timeout — a small class of patterns (a repeated group containing another repeated element is the classic shape) can make a single match attempt take exponentially longer as the input grows, and nothing in JavaScript can interrupt that once it starts. This tool watches for the most common version of that shape and warns you before it happens, but it’s a heuristic, not a guarantee — see the FAQ below for the honest limit of what it can catch.
Examples
- Validating an email address — test a pattern like <code>^[\w.+-]+@[\w-]+\.[a-z]{2,}$</code> against a list of addresses, one per line, and see at a glance which ones match and which don't, without writing a single line of code to check.
- Extracting every URL from a block of pasted text — a pattern like <code>https?:\/\/\S+</code> with the <code>g</code> flag highlights every match in a paragraph of notes or a log excerpt, then Copy Matches pulls just the URLs out, one per line. For decomposing one of those URLs further once you've found it, see URL Parser.
- Parsing a date into its parts with named capture groups — a pattern like <code>(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})</code> against <code>2026-08-06</code> shows the year/month/day groups broken out individually below the match, the same shape you'd read them back out with in code via <code>match.groups.year</code>.
Frequently asked questions
Which regex flavor does this use?
RegExp — the same engine your browser and Node.js use, not PCRE, Python's re, or any other language's regex dialect. Most everyday patterns behave identically across flavors, but some syntax genuinely differs (for example, JavaScript's named groups use (?<name>...), and lookbehind support depends on the flag set). If you're writing a pattern for a different language, test the final version there too rather than assuming a perfect match.What do the g/i/m/s/u flags do?
g (global) finds every match instead of stopping at the first one — leave it off to test just the first match, as most single-value validation patterns do. i makes matching case-insensitive. m (multiline) makes ^ and $ match at the start/end of each line rather than only the start/end of the whole string. s (dot-all) makes . also match newline characters, which it skips by default. u (unicode) makes the pattern treat astral characters — most emoji, for instance — as one code point instead of two separate UTF-16 units.Can a pattern here freeze my browser tab?
(a+)+, against the wrong input) trigger catastrophic backtracking: the regex engine's own matching attempt can take exponentially longer the more the input grows, and once a single match attempt starts, nothing in JavaScript can interrupt it mid-flight. This tool flags the single most common shape behind that risk before it runs — but it's a pattern-shape heuristic, not a full analysis, so it won't catch every pathological pattern. If a tab does become unresponsive, reload it — nothing you typed here is saved or sent anywhere, so there's nothing to lose.Does this validate that my pattern is 'correct'?
How are capture groups shown?
(?<year>...)) show their name alongside their numbered position, positional groups show just the number, and a group that didn't participate in a particular match (common with alternation, like (a)|(b) matching "b") is shown as such rather than silently omitted. In the highlighted preview itself, a capture group nested directly inside another capture group is shown as part of its outermost group only — its own value is still listed correctly below, just not separately outlined inline.