Text & String Tools

Regex Tester and Explainer

Write a pattern, paste some text, and see every match highlighted as you type. Capture groups are broken out per match, and the explainer describes what each part of the pattern actually does — which is usually the fastest way to find the mistake.

  • Free, no sign-up
  • Runs in your browser
  • Nothing uploaded
  • Updated Sep 2026
Pattern
/ /
Test string
Highlighted result

Matches

What this pattern does

Enter a pattern to begin

At a glance

Flavour
JavaScript (ECMAScript) — the flavour your browser runs
Flags
g, i, m, s, u, y
Shows
Matches, capture groups, named groups, positions
Also does
Replace preview with group references
Processing
Entirely client-side
Cost
Free, no account

Regex flavours are not interchangeable

This tester uses the JavaScript engine, because it runs in your browser. Most patterns behave identically across languages, but the differences catch people out when a pattern that works here fails in production.

The ones that matter: JavaScript has no \A or \z anchors — use ^ and $ with the m flag off. Lookbehind ((?<=...)) is supported in modern browsers but not in Safari before 16.4, and not in older Node. Unicode property escapes like \p{L} require the u flag. PCRE features such as atomic groups, possessive quantifiers and recursion do not exist in JavaScript at all.

Going the other way, Python's re module needs re.DOTALL where JavaScript uses the s flag, and Python names groups with (?P<name>...) rather than (?<name>...). If a pattern is destined for a different language, test it there before shipping.

Greedy, lazy, and the mistake everyone makes

By default, quantifiers are greedy: .* matches as much as it possibly can, then backtracks only as far as needed. This produces the single most common regex bug.

Given <b>bold</b> and <b>more</b>, the pattern <b>.*</b> matches the entire string, not the first tag — because .* swallows everything and then backs up to the last </b>. Adding ? makes it lazy: <b>.*?</b> stops at the first closing tag, which is almost always what was intended.

Better still, avoid . when you can name what you actually want. A negated character class like [^<]* is both clearer and faster, because it cannot match past the boundary in the first place and so never needs to backtrack.

That last point is not only about elegance. Patterns with nested quantifiers — the classic shape being (a+)+ — can take exponential time on input that nearly matches. This is catastrophic backtracking, and on a server processing user input it is a denial-of-service vulnerability. If a pattern hangs this tester, it will hang your application too.

Capture groups worth knowing

Parentheses do two jobs — grouping and capturing — and being deliberate about which you want makes patterns much easier to read.

  • (...) captures, and the result is available as $1, $2 and so on in replacements.
  • (?:...) groups without capturing. Use it whenever you only need the grouping, so your numbered groups stay meaningful.
  • (?<name>...) captures by name, retrieved as $<name>. Far more maintainable than counting parentheses, and the right default for anything you will still be reading in six months.
  • (?=...) and (?!...) are lookahead assertions: they test what follows without consuming it. Useful for rules like "a digit not followed by a percent sign".

A practical note on validation. Regular expressions are excellent for extracting structure from text and poor for validating it. Email addresses in particular are a trap — the fully correct pattern runs to thousands of characters, and every short version rejects valid addresses. Check for an @ with something on either side, then send a confirmation email. That is what actually establishes an address is real.

How to use the Regex Tester

  1. Enter your pattern

    Write it without the surrounding slashes. Set flags separately below — g for all matches, i for case-insensitive, m for multi-line anchors.

  2. Paste sample text

    Include cases that should match and cases that should not. A pattern that matches everything is as broken as one that matches nothing.

  3. Read the explanation

    The explainer breaks the pattern into tokens and describes each one. When a pattern misbehaves, this usually shows why faster than staring at it.

  4. Test a replacement

    Use the replace field with $1 or $<name> to reference captures, and check the preview before running it on real data.

Frequently asked questions

Which regex flavour does this use?

JavaScript, because it runs in your browser. Most patterns are portable, but lookbehind, Unicode property escapes and named-group syntax differ across languages — test in your target environment before shipping anything important.

Why does my pattern match more than expected?

Almost certainly greedy quantifiers. .* takes as much as it can, so <b>.*</b> spans from the first opening tag to the last closing one. Add ? to make it lazy, or better, replace . with a negated class such as [^<]*.

What does the g flag change?

Without it, matching stops at the first result. With it, every match is found. It also makes the regex object stateful through lastIndex, which is a classic source of bugs when the same object is reused across calls in a loop.

Can I use regex to validate email addresses?

You can check for an @ with plausible text either side, and that is about as far as it is worth going. The fully RFC-correct pattern is thousands of characters long, and every short version rejects valid addresses. Sending a confirmation email is the only real validation.

Why did my pattern freeze the page?

Catastrophic backtracking — nested quantifiers such as (a+)+ on input that nearly matches can take exponential time. Restructure the pattern to remove the nesting. If it hangs here, it will hang your server too, which on user-supplied input is a denial-of-service risk.

Should I use regex to parse HTML?

No. HTML is not a regular language — nesting, optional closing tags and attributes containing angle brackets all defeat regular expressions. Use a DOM parser. Regex is fine for pulling a simple value out of well-known, well-formed markup and unreliable for anything more.