Free Regex Tester Online

Test a JavaScript regular expression against your text. Matches highlight as you type, with match positions, numbered and named groups, and i, m, s, u flags.

No login. Files processed for your request and discarded. Unlimited use. Files processed & discarded →

Compress PDF — it's free or choose from 164+ tools

164+ Free Tools
— Files Processed
— Happy Visitors
— Pages Explored
0 Files Stored

Regex Tester — Test Regular Expressions Online

Part of Text tools: See all Text tools.

What is Regex Tester?

This regex tester runs a JavaScript regular expression against text you paste and highlights every match as you type. For each match it shows where the match starts and the text of each numbered and named capture group. You can switch on the i, m, s and u flags with one click. Matching is done by your browser's own JavaScript regex engine, so the pattern and the text are not sent to our server.

How to use Regex Tester

  1. Type the pattern in the Regular expression box without the surrounding slashes, for example (\d{4})-(\d{2})-(\d{2}) for a date.
  2. Paste sample text into the Test string box. Include lines that should match and lines that should not.
  3. Tick any flags you need: Ignore case (i), Multiline (m), Dot matches newline (s) or Unicode (u). Every match is always found, as if the g flag were on.
  4. Read the highlighted text and the match list, adjust the pattern until only the right text is matched, then copy it into your code and test it there too.

Why use this tool?

Regular expressions are easy to get almost right. A pattern that is too greedy or is missing an anchor can quietly match the wrong text. Seeing the highlighted matches and the capture groups while you edit shows those mistakes straight away, before the pattern reaches your code.

Why you should never debug a regex inside your app

A regular expression is a tiny, dense program for matching patterns in text, and like any program it is written by trial and error far more than by inspiration. The slow way to develop one is to embed your best guess in application code, run the program, watch it fail, tweak the pattern, recompile or reload, and repeat — a thirty-second loop for a one-second change. The fast way is to paste a representative sample of your real text into a tester, type the pattern, and watch matches light up as you type. This tool exists to collapse that feedback loop to nothing: every keystroke re-runs the match against your sample, highlights what matched, and shows you the capture groups, so you build the pattern by watching it work rather than by guessing.

Matches, groups, and why the highlighting matters

Two kinds of feedback do most of the work. The first is the highlighted matches — the exact spans of your text the pattern claims. This instantly catches the most common regex bug, which is matching too much: a greedy pattern that you intended to grab one tag swallows everything from the first tag to the last. Seeing the highlight stretch across half your sample tells you in a glance what a wall of code never would. The second is capture groups — the parenthesised sub-parts you pull out of each match. When you write (\d{4})-(\d{2})-(\d{2}) to parse a date, the tester shows you group 1 = year, group 2 = month, group 3 = day for each match, so you can confirm you are extracting the pieces you think you are before you wire them into code.

Flags change everything — set them deliberately

The same pattern behaves completely differently depending on its flags, and forgetting one is a frequent source of "it works in the tester but not in my code" confusion. The global (g) flag finds every match rather than just the first — essential when you are extracting all the URLs from a document, not just the first one. Case-insensitive (i) makes Error match error and ERROR, which you almost always want when matching words in human text and almost never want when matching a case-sensitive token. Multiline (m) changes what ^ and $ mean: normally they anchor to the start and end of the whole text, but with m they anchor to the start and end of each line — the difference between "does the document begin with..." and "does any line begin with...". Set these consciously; most surprises trace back to a flag that was on or off without your noticing.

Greedy, lazy, and the most expensive mistake

By default, quantifiers like *, +, and {2,} are greedy: they match as much as they possibly can while still allowing the overall pattern to succeed. So ".*" against "a" and "b" matches the whole thing from the first quote to the last, not the first quoted word — usually not what you meant. Adding a ? makes a quantifier lazy: ".*?" matches as little as possible, grabbing just "a". The tester's live highlighting makes the greedy/lazy distinction obvious instantly, which is exactly the kind of thing that is invisible until you see it overshoot.

Greed also has a performance cliff worth respecting: catastrophic backtracking. Certain patterns — typically nested quantifiers like (a+)+ applied to input that almost matches — force the engine to try an exponential number of combinations before giving up. On a short test string it is instant; on a long line of production input it can hang a thread for seconds or lock up a server, and it has caused real-world outages (a single bad regex has taken down major websites). Testing your pattern here against a deliberately long and slightly-malformed sample is a cheap way to catch a pattern that is correct but dangerously slow before it reaches production.

Regex flavours are not identical

"Regular expression" is a family, not a single standard. JavaScript, Python, PCRE (PHP/Perl), Java, Go (RE2), and the POSIX tools grep/sed agree on the basics but diverge on the edges: lookbehind support, named-group syntax ((?P<name>...) in Python versus (?<name>...) elsewhere), Unicode handling, and whether backreferences exist at all (RE2, which powers Go and parts of Google's infrastructure, deliberately omits them to guarantee no catastrophic backtracking). A pattern that works perfectly in one engine can throw a syntax error in another. When you build a pattern in any tester, note which flavour it uses and re-check the exotic features against your target language's documentation before deploying.

A workflow that produces patterns you can trust

Build incrementally. Start with the simplest pattern that matches your easiest example, confirm it highlights correctly, then add one piece of complexity at a time, watching the matches after each addition. This way, when a change breaks the match, you know exactly which addition did it. Test against both strings that should match and strings that should not — a validation regex that accepts every valid email but also accepts not-an-email is worse than useless, and only negative test cases reveal that. Throw in the awkward edge cases on purpose: empty input, a value with trailing spaces, the longest realistic line, the entry with unusual characters. Patterns extracting phone numbers, dates, URLs, or custom log formats almost always have an edge case that the happy-path sample never exercises. When you are done, you should be able to paste a brand-new sample and feel confident, not hopeful, about what the pattern will do.

Frequently asked questions

Which regex flavor does this tester use?
JavaScript (ECMAScript), using the regex engine of the browser you are using. It is not PCRE, Python or Java. Most everyday syntax works the same in all of them, but some features differ, so test the final pattern in your own language as well.
Will my Python or PHP regex work here?
Usually, for common syntax such as character classes, quantifiers, groups and anchors. Differences to watch: Python writes named groups as (?P<name>...) while JavaScript uses (?<name>...); \A and \Z are not supported in JavaScript; an inline flag such as (?i) at the start of a pattern is rejected, so use the flag checkboxes instead; and PCRE features such as possessive quantifiers, atomic groups and recursion do not exist in JavaScript.
What do the flags do?
i ignores case, so cat also matches Cat and CAT. m makes ^ and $ match at the start and end of every line instead of only the whole text. s lets the dot match line breaks. u turns on Unicode mode, which you need for property classes such as \p{L} and for treating an emoji as one character. The tester always finds every match, as if g were on.
How do I use capture groups and named groups?
Wrap part of the pattern in parentheses to capture it, and each match then lists Group 1, Group 2 and so on. Name a group with (?<year>\d{4}) and it is also listed under its name. A group that did not take part in a match is shown as did not participate. Use (?:...) when you need grouping but do not want to capture.
Why did the page freeze on my pattern?
Some patterns, such as nested quantifiers like (a+)+ run against long text that almost matches, make the regex engine try a huge number of combinations. This is called catastrophic backtracking. The tester runs in your tab, so a pattern like that can make the tab stop responding. Reload the page and rewrite the pattern with a narrower character class or fewer nested quantifiers. A pattern that freezes here would also be slow in production.
Is there a limit on matches or text size?
The match list shows the first 1,000 matches. There is no fixed limit on text size, but everything runs on your device, so very large pastes take longer. The pattern and the test string stay in your browser and are not sent to our server.

Step-by-step guides

Also try

Related tools that work well with this one: