Developer tools

Regex tester and explainer

The hard part of writing a regular expression is seeing what it actually matches. Type a pattern and some text: every match is highlighted as you type, capture groups are listed in a table, the replacement is previewed, and the pattern is broken into small pieces with a plain-English explanation of each.

Matches and groups
Replace
Explanation

    Runs entirely in your browser. Nothing you enter here is uploaded.

    How to use it

    1. Type the pattern in "Regular expression" without the surrounding slashes, and tick the flags below. The most common are g (find all matches) and i (ignore case).
    2. Paste the text to search into "Test text". Matches are highlighted as you type, alternating colours so neighbouring matches are easy to tell apart; an empty match appears as a thin bar.
    3. The "Matches and groups" table lists the position and text of every match and what each numbered and named group captured.
    4. Open "Replace" and type a replacement to preview the result. Use $1, $2 for numbered groups, $<name> for named groups and $& for the whole match.
    5. "Explanation" breaks the pattern into pieces and says what each one does. When you inherit a regex you do not understand, paste it here first.

    How matching works

    JavaScript regular expressions

    The tool uses your browser's own JavaScript regex engine, so results are exactly what your web page or Node.js code will see. MDN's guide describes the flags: g finds every match instead of the first; i ignores case; m makes ^ and $ match at the start and end of each line rather than of the whole text; s lets . match line breaks; u treats the pattern as Unicode code points and enables property escapes such as \p{…}; y requires each match to start exactly where the last one ended. Python, Java and PCRE are broadly similar but differ in details such as lookbehind and named-group syntax, so test again before moving a pattern to another language.

    The \w trap

    According to MDN, \w matches only A–Z, a–z, 0–9 and the underscore. \w+ finds only "caf" in "café", and nothing at all in Chinese or Greek text. With the u flag, use \p{L} for any letter or \p{Script=Han} for Chinese characters. The word boundary \b uses the same definition of a word character, so there is no boundary between two Chinese characters.

    Empty matches

    A pattern that can match an empty string, such as a*, matches "baaa" three times: an empty match at 0, "aaa" at 1 and an empty match at 4. After an empty match the tool moves forward one character (one whole code point with the u flag, so an emoji is never split), which keeps it from looping forever; the table shows where these empty matches are.

    Why a pattern can time out

    Some patterns try an astronomical number of combinations before giving up, which is called catastrophic backtracking. OWASP's example is ^(a+)+$: each extra "a" in the input doubles the number of paths to try. In production, one crafted input can take a service down this way. This tool runs the regex in a background thread and stops it after 1.5 seconds with a warning instead of freezing the page. If you see it, rewrite the pattern to remove the nested quantifier.

    Where the common patterns come from

    The email pattern is the one in the HTML specification — the rule browsers use for <input type=email>. It is stricter than what RFC 5322 allows but accepts practically every address in real use. The UUID pattern follows the text format in RFC 9562: 8-4-4-4-12 hexadecimal digits. The others (IPv4, date, colour, Chinese mobile number, URL) are common forms that check the shape only, not the meaning: the date pattern accepts 2026-02-31.

    Examples

    PatternFlagsTextResult
    \d+ga1 b22 c3331, 22, 333
    (?<year>\d{4})-(\d{2})g2026-09 and 2027-01Two matches; year is 2026 and 2027
    a*gbaaaEmpty at 0, aaa at 1, empty at 4
    \w+g中文abcOnly abc
    \p{Script=Han}+guabc中文def中文

    Replace example: with (\w+)@(\w+) and the replacement "$2 at $1", "a@b c@d" becomes "b at a d at c". Named groups work the same way: (?<y>\d{4}) replaced with [$<y>] turns 2026 into [2026].

    Limits

    • JavaScript syntax only. Python's (?P<name>…), and PCRE features such as possessive quantifiers and recursion, fail or mean something else.
    • Highlighting shows the first 1,000 matches and the table the first 200, but the total is always counted.
    • The explanation covers common syntax token by token; it does not describe the overall intent of a complex pattern.
    • The common patterns check format only. Whether an address receives mail or a date exists needs other checks.

    Frequently asked questions

    Why does \w not match é or Chinese characters?

    In JavaScript \w means A–Z, a–z, 0–9 and underscore only. Turn on the u flag and use \p{L} or \p{Script=Han}.

    Do I type the slashes?

    No. Slashes are JavaScript source syntax; choose the flags with the checkboxes.

    How do I refer to a group in the replacement?

    $1, $2 and so on for numbered groups, $<name> for named groups and $& for the whole match.

    Why did it time out?

    The pattern is probably backtracking catastrophically, usually because of nested quantifiers such as (a+)+. The tool stops after 1.5 seconds so the page stays responsive.

    Is my text uploaded?

    No. Matching runs in a background thread in your browser.

    Sources and further reading

    ↵ to open · Esc to close