Regex Tester

Test regular expressions against your text with every match highlighted, a full match list and capture groups — plus one-click patterns for emails, URLs and dates. Free, no sign-up — runs locally in your browser.

Flags:

Your work is auto-saved in this browser only, so a refresh won't lose it. Nothing is uploaded.

No matches yet — type a pattern and some test text.

    What this tester does

    A regular expression is a small program that describes a shape of text, and the fastest way to understand one is to watch it work. Type a pattern, tick the flags it runs under, and give it some real text: every match is highlighted in place, listed with its exact position, and unfolded into its capture groups. There is no Run button because there is nothing to wait for — the results update as you type, compiled and executed by the same JavaScript RegExp engine you would ship against, so what matches here is what matches in your code, including the awkward cases. The companion regex cheat sheet covers the syntax itself; this page is the workbench next to it.

    How to use it

    1. Start from a preset if your shape is a common one — email, URL, ISO date, phone number, IPv4 address, hex colour. Each preset fills in a pattern and a sample text with deliberate near-misses, so you can see both what matches and what correctly does not.
    2. Edit the pattern and watch the highlights move. The match list below numbers every match and shows its start and end positions; expand a match to see what each capture group caught.
    3. Toggle flags one at a time. Most regex confusion is flag confusion: m changes what ^ and $ mean, s changes what . means, and i is usually the difference between a pattern that works on your sample and one that works on production data.
    4. Break it on purpose. Remove an anchor, loosen a quantifier, and look at the extra matches — a pattern is defined as much by what it wrongly accepts as by what it catches.

    Reading the results

    The highlight view answers "where does it bite?" and the list answers "what exactly did it take?". A match entry shows the matched text and its character offsets in the test string — offsets count from 0, the convention your code uses, so a match at index 4 is the fifth character. Groups are listed under their match in order: numbered groups first, then any named groups. A group shown as undefined sat inside a branch that did not run — an alternation like (cat)|(dog) always leaves one of its two groups undefined, which is normal and is exactly the kind of thing that surprises people in production. Zero-width matches — where the pattern matched the empty string — appear as thin markers; they are real matches, and the scan steps past them so a pattern built on * cannot loop forever. If a pattern can match in more than a thousand places the list stops at 1,000 and says so: by then the question is never the 1,001st match, it is why the pattern is that permissive.

    Three habits worth stealing

    Anchor before you optimise. Most runaway patterns are simply unanchored: \d+ finds digits anywhere, including inside words and prices, while \b\d+\b or ^\d+$ says which digits you meant. Test the negative cases. Every preset sample here includes strings that must not match — a date with month 13, an IP-shaped 300.1.1.1 — because a pattern you have only fed valid input has not been tested at all. Beware nested quantifiers. A shape like (a+)+$ against a long almost-matching string can take exponential time ("catastrophic backtracking"); if this page ever feels slow while you type, you have found one, and the fix is almost always to make the inner and outer quantifiers want different characters. Your browser runs the pattern, so a runaway pattern can only stall this tab — in a server it would stall a request queue.

    Frequently asked questions

    What do the flags g, i, m, s, u and y mean?

    g (global) finds every match instead of stopping at the first; i makes matching case-insensitive; m lets ^ and $ match at line boundaries inside a multi-line text, not just at its ends; s lets . match newline characters too; u switches the pattern to Unicode mode, where character classes and escapes behave per code point (needed for correct emoji handling); y (sticky) requires each match to start exactly where the previous one ended. This tester always lists every match it can find — the flags still change what matches, and a sticky pattern still stops at the first gap, exactly as it would in your code.

    What is a capture group?

    Any part of the pattern wrapped in parentheses is a capture group: when the pattern matches, the engine remembers what that part consumed. Groups are numbered by their opening parenthesis, left to right — (\d+)-(\d+) has group 1 for the digits before the hyphen and group 2 for the digits after. Writing (?:…) makes a group that organises without capturing, and (?<name>…) gives a group a name you can reference. The match list under the tester expands every group for every match, including groups that did not participate (shown as undefined).

    Why does my pattern match an empty string everywhere?

    Because something in it can match zero characters: *, ?, {0,} and lazy quantifiers all allow that, and a pattern like a* genuinely matches the empty string at every position of any text. The tester still lists those zero-width matches (and steps past them so the scan terminates) — in production code they are usually the sign that a quantifier should be + instead, or that an anchor is missing.

    Are the preset patterns production-ready?

    They are teaching-grade: right for the overwhelmingly common shapes and honest about their limits. The email pattern, for instance, accepts the addresses people actually have but is not a full RFC 5322 grammar — no regex is, really; the only reliable way to validate an email address is to send it a message. Use the presets as starting points and as test material, and tighten them against your real data.

    Is my test text uploaded anywhere?

    No. The pattern is compiled and run by your own browser's JavaScript engine — the same RegExp implementation your code would use — and nothing leaves the page. Your pattern and test text are kept only as a local draft in your browser, like the other tools on this site.

    Related tools

    Related guides