A regex tester is one of the most-used developer tools because regular expressions are unforgiving: a misplaced parenthesis or an unescaped dot can change the meaning entirely, and the failure mode is silent — your pattern compiles, just matches the wrong things. This tool gives you fast feedback: type a pattern, see exactly what matches, examine the capture groups, preview substitutions.
How it works
The pattern is compiled with the JavaScript RegExp constructor and applied with String.prototype.matchAll. Every match is logged with its full text, start and end offsets, and per-group captures (numbered $1, $2 and named (?<name>...)). The matcher always runs with the global flag — toggling it off would hide matches you’d want to see — and other flags (i, m, s, u) are togglable.
A safety cap of 500 matches prevents accidental tab freezes when a permissive pattern hits a large input. Hit the cap? Refine the pattern until your real matches fit under it.
Example: extracting email domains
Pattern: (\w+)@(\w+\.\w+) against contact alice@example.com or bob@test.org for details produces two matches. Group 1 captures the local part (alice, bob), group 2 captures the domain (example.com, test.org). Switch to Replace mode with $1 [at] $2 and the text becomes contact alice [at] example.com or bob [at] test.org for details — a quick way to obfuscate emails in static content.
Example: validating a date format
Pattern: (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) against event on 2024-03-15 matches once. The named groups (year, month, day) appear in the per-match table — much clearer than $1, $2, $3. Note that this pattern checks structure, not validity: it’ll happily match 2024-13-99. Range validation requires either richer regex constraints or a follow-up parse step.
Example: stripping HTML attributes
Mode: Replace. Pattern: \s+\w+="[^"]*" against <a href="x" target="_blank" class="btn">link</a> with empty replacement leaves <a>link</a>. Useful for one-off HTML cleanup, though for serious HTML manipulation use a parser — regex is famously bad at handling nested or self-closing markup.
When regex is the wrong tool
- Parsing nested structures (HTML, JSON, XML, source code). Use a real parser. Regex can’t count matched parens or quotes correctly past one level of nesting.
- Replacing within strings while ignoring matches inside other strings. Without a tokeniser, regex doesn’t know “inside a quoted string” from “outside one.”
- Validating semantic correctness. A pattern that matches the shape of an email address won’t tell you the address is real, deliverable, or even RFC-compliant in edge cases.
Common gotchas
Unescaped dot. example.com in a pattern matches examplexcom too — the dot is a metacharacter for “any char.” Write example\.com to match a literal dot.
Greedy vs lazy. <.*> matches <a><b> as one match (greedy: extends as far as possible). <.*?> matches <a> and <b> separately (lazy: shortest possible). Most “why does my regex match too much?” questions come down to greedy quantifiers.
Anchors with multiline. ^ and $ match start/end of the whole input by default. With the m flag they match start/end of each line. If your input has newlines and you want per-line matching, toggle m.
Backreferences in replacement. $1 is the first capture group’s text; $& is the entire match; $$ is a literal $. Forgetting $$ for a literal dollar sign produces empty output where you wanted a $.
For full-document find and replace with the same regex engine on prose (not code), the find and replace tool is the counterpart; for selection inside JSON specifically, the JSONPath tester is shape-aware and safer than regex.