What is Regex Tester?
Regex Tester is a browser-based tool for developing and debugging regular expressions. You type a pattern and choose flags, paste sample text, and instantly see every match highlighted along with its numbered and named capture groups. It uses the JavaScript regular-expression engine, the same one that runs in browsers and Node.js.
A regular expression is a compact pattern language for finding and extracting text — validating an email format, pulling values out of a log line, splitting structured strings, or performing find-and-replace. Regexes are powerful but notoriously hard to write correctly by hand, and a small mistake can silently match too much, too little, or the wrong thing.
To keep the tool responsive, matching runs in a background Web Worker with a timeout. This means a pathological pattern that triggers catastrophic backtracking cannot freeze the page — the tool detects the runaway, stops it, and tells you what happened. Everything runs locally, so your test text is never uploaded.
Why use Regex Tester?
Writing a regex without immediate feedback is guesswork. Seeing matches update live as you adjust the pattern turns a frustrating trial-and-error loop into a fast, visual process — you can watch exactly what your pattern captures and refine it until it is right, instead of discovering problems later in production code.
Capture groups are where regexes get genuinely useful and genuinely confusing. The tool breaks out each numbered and named group per match, so you can confirm you are extracting the right substrings before wiring the pattern into your application. This is invaluable for parsing and data-extraction work.
The background-worker safety net matters more than it sounds. Certain patterns applied to certain inputs can take exponential time (catastrophic backtracking), hanging a normal tester and your browser tab with it. Here, the timeout catches that and warns you, so you learn your pattern is dangerous in a safe environment rather than in a live server. And because everything runs locally, sensitive test data stays on your machine.
Features
- Live matching against sample text as you type
- Toggle the g, i, m, s, and u flags
- Shows every match with its index in the text
- Breaks out numbered and named capture groups per match
- Runs matching in a background worker so the page never freezes
- Timeout protection against catastrophic backtracking
- Copy any individual match to your clipboard
- Runs entirely in your browser — no uploads, works offline
How to use Regex Tester
- Type your regular expression into the pattern field (no surrounding slashes needed).
- Toggle the flags you need — g for global, i for case-insensitive, m for multiline, s for dotall, u for unicode.
- Paste the text you want to test against into the test-text panel.
- Watch the matches panel populate live, with each match's position and capture groups.
- Copy any match you need, or adjust the pattern and flags until the matches are exactly what you want.
Example 1 — Extract numbers
A simple pattern with the global flag finds every run of digits in the text.
Input
Pattern: \d+ · Text: order 42, item 7Output
Match 1: "42" at index 6 · Match 2: "7" at index 16Example 2 — Named capture groups
Named groups let you label the parts you extract, which the tool lists per match.
Input
Pattern: (?<year>\d{4})-(?<month>\d{2}) · Text: 2024-12Output
Match 1: "2024-12" · year: 2024 · month: 12Common Mistakes
- Forgetting the global flag: without g, matching stops at the first result. If you expect every occurrence and only see one, enable the g flag.
- Not escaping special characters: characters like . * + ? ( ) [ ] are operators. To match them literally you must escape them (\.), or use the Escape / Unescape tool to escape a literal string for regex.
- Assuming the dot matches newlines: by default . does not match line breaks. Enable the s (dotall) flag if you need it to span lines.
- Catastrophic backtracking: nested quantifiers like (a+)+ against certain inputs can take exponential time. If the tool reports a timeout, your pattern is dangerous and needs simplifying before use in production.
- Confusing regex dialects: this uses the JavaScript engine, which differs from PCRE, Python, or .NET in some features (like lookbehind support and certain escapes). A pattern from another language may behave differently here.
- Greedy vs lazy quantifiers: * and + are greedy and match as much as possible. If a group captures too much, add ? to make it lazy (*?, +?) so it matches the minimum.
Developer Tips
- Build patterns incrementally — start with a small piece that matches, confirm the groups, then extend it — rather than writing a long pattern all at once and debugging it blind.
- Use named capture groups ((?<name>...)) instead of relying on group numbers; they make both your pattern and the code that consumes it far more readable.
- If you need to match arbitrary user text literally inside a larger pattern, escape it first with the Escape / Unescape tool's regex flavor to neutralize any metacharacters.
- Prefer specific character classes over the dot where possible; overusing .* is a common cause of both wrong matches and backtracking slowdowns.
- Remember this is the JavaScript flavor — if you are porting a pattern from Python or PCRE, verify features like lookbehind and Unicode property escapes behave as you expect.
Frequently Asked Questions
- What regex flavor does this tool use?
- It uses the JavaScript regular-expression engine, the same implementation used by browsers and Node.js. This matters because regex dialects differ: JavaScript supports named groups, lookahead, and (in modern engines) lookbehind and Unicode property escapes, but its syntax and available features are not identical to PCRE, Python's re module, or .NET. If you are copying a pattern from another language, test it here to confirm it behaves the same, since some constructs are engine-specific.
- What do the g, i, m, s, and u flags do?
- The g (global) flag finds all matches instead of stopping at the first. The i (ignore case) flag makes matching case-insensitive. The m (multiline) flag makes ^ and $ match at line boundaries rather than only the start and end of the whole string. The s (dotall) flag lets the dot match newline characters, which it does not by default. The u (unicode) flag enables full Unicode handling, including Unicode property escapes and correct treatment of characters outside the basic range.
- Why did my pattern time out?
- Certain patterns — especially those with nested quantifiers like (a+)+ or (a*)* — can trigger catastrophic backtracking, where the engine explores an exponential number of possibilities against certain inputs and effectively hangs. Because matching runs in a background worker with a timeout, the tool detects this, stops the runaway match, and warns you instead of freezing. A timeout is a strong signal that the pattern is unsafe to use in production; simplify it, avoid nested quantifiers, or make quantifiers more specific.
- Is my test text uploaded anywhere?
- No. Both the pattern and the test text are processed entirely in your browser, inside a local Web Worker. Nothing is sent to a server, logged, or stored, so you can safely test patterns against sensitive data like logs or personal records. You can verify this by opening your browser's Network tab while testing: there are zero outbound requests, and the tool continues to work even offline.
- What is the difference between numbered and named capture groups?
- Numbered groups are created by plain parentheses and are referenced by their position — group 1, group 2, and so on, counted by opening parenthesis. Named groups use the syntax (?<name>...) and are referenced by a descriptive label instead of a number. Named groups make patterns much easier to read and maintain, and they keep the code that consumes matches from breaking when you add or reorder groups. This tool lists both kinds for every match so you can see exactly what each captures.
- Why does my pattern match too much text?
- This is usually caused by greedy quantifiers. By default, * and + match as much as they possibly can while still allowing the overall pattern to succeed, so something like <.*> will match from the first < to the last > on a line, swallowing everything in between. To fix it, make the quantifier lazy by adding a ? (for example <.*?>), so it matches the smallest amount possible, or use a more specific character class instead of the dot to constrain what it can consume.