Regex Tester
Test regular expressions live, highlight every match, list capture and named groups, then flip to replace mode to transform text with $1 group references. Runs fully in your browser.
- Free, no account
- No watermark
- No usage limit
About the Regex Tester
Most quick online regex testers stop at matching. You paste a pattern, it highlights what hits, and that is the whole show. But half the time the reason you are testing a regex is that you want to change the text, reformat a column, strip a prefix off a few hundred lines, swap two fields around. A match-only tester leaves you squinting at highlights, guessing what your replacement will actually spit out. This one has a real replace mode. Type a replacement like $1-$2, and the transformed text appears live underneath as you type, so you see the exact output before it ever touches your code.
That is the part the throwaway testers skip and the part you actually need. It supports the full replacement syntax the language uses, $1 and $2 for numbered groups, $<name> for named ones, $& for the whole match, and an empty replacement to just delete every hit. Watch the result change with each keystroke, then copy it out. No sending your text to a server and waiting, no fiddly export step.
It also never uploads anything. The text you throw at a regex is usually the sensitive stuff, a production log, a customer export, an API response with real names and addresses in it. Paste that into some random tester and you have handed a machine you do not control the exact data you are paid to protect. Here the text stays in the tab, with nothing sent out and no round trip, and it keeps working with your wifi switched off. That is not a nice-to-have for anyone who tests patterns against real data.
How to use
- Type your pattern in the regex field and switch on the flags you need (g, i, m, s, u).
- Type or paste your text into the test box, or drop a text file straight onto it (a log, a CSV, an export). Big files are fine, they load right in the browser.
- Leave it in Match mode to see every hit highlighted with its position and groups, or flip to Replace mode.
- In Replace mode, type your replacement string. The transformed text shows up live below the highlights.
- Tweak the pattern and replacement until the output is exactly right, then copy the matches or the result and paste it into your code.
Replace mode is the whole point
You have a list of dates as 03/14/1999 and you need them as 1999-03-14. You write (\d{2})/(\d{2})/(\d{4}), you type $3-$1-$2 in the replacement, and the reordered dates appear underneath instantly. No mental simulation, no running it in a scratch file first to check. If it looks right, you can trust it, because you are looking at the actual output of the engine.
Named groups make this a lot more readable. Instead of counting parentheses to remember whether the last name is $2 or $3, you name them. A pattern like (?<first>\w+) (?<last>\w+) with a replacement of $<last>, $<first> turns "Ada Lovelace" into "Lovelace, Ada", and the group names carry their own meaning so you can read the replacement back a month later and still know what it does. The match list below shows named groups next to the numbered ones, so you can confirm what got captured under each name.
Without the g flag, replace only touches the first match, exactly like a real replace call in code. With g on, it replaces all of them. The tool follows that rule faithfully, so if your output only changed the first hit, look at the g button. It will tell you how many matches you left on the table.
Reading the match details
Every match is listed with the index where it starts and the exact substring it grabbed, which is how you catch a pattern that is matching more (or less) than you meant. Under each match you get its capture groups in order, and any named groups spelled out by name. An empty capture shows as (empty) and a group that did not participate shows as undefined, because those two are genuinely different and blurring them is how a bug sneaks through. There is a running count at the top so you know instantly whether your pattern found three things or three hundred.
Common regex bugs you can catch live
Most regex bugs are not exotic. They are the same handful, over and over, and watching them highlighted live is how you catch them in seconds instead of an hour of print statements.
Greedy matching is the most common one. By default .* grabs as much as it can, so a pattern meant to pull one quoted string or one tag will happily swallow everything up to the last one on the line. The fix is usually a lazy .*?, or being specific about what you actually want instead of saying "anything". When the yellow highlight covers half your text, the problem is obvious.
Escaping catches people constantly, because a bare dot matches any character until you write it as \., so a pattern for an IP address or a filename that "sort of works" is often matching things it was never meant to. Same story for parentheses, brackets, and the other characters the engine treats as special. And anchors matter more than they look. Without ^ and $, a pattern that seems to validate an input will cheerfully match it inside a longer string, so "abc" sails through a check that was meant to reject "xabcx". If you are validating, anchor both ends.
The u flag catches people once they are past the basics. Unicode property escapes like \p{L} for any letter, or \p{Script=Cyrillic} for a whole alphabet, only mean anything with u switched on. Leave it off and JavaScript reads \p{L} as the four plain characters p, {, L and }, which match nothing in ordinary text and raise no error either, so you get a confident zero and no reason to doubt it. Type a pattern with \p{...} or \u{...} in it here and the page tells you the flag is missing before you go hunting for the fault in your test data instead. Switching u on is stricter in the other direction too, since an escape like \- that JavaScript tolerates without it becomes a syntax error with it, which is the same error your code would throw.
Do not try to parse HTML or JSON with a regex. Those are nested structures and the engine genuinely cannot handle nesting, so whatever you build passes your three test cases and then breaks on the fourth, which is the point to stop and use a real parser. Regex is very good at finding and pulling structured pieces out of flat text, and testing that live is exactly what this tool is for. Push it much past that and it stops being reliable.
Frequently asked questions
How do I do find and replace with regex here?
Switch to Replace mode, write your pattern, then type the replacement string in the new field. Reference captured groups with $1, $2, and so on, or by name with $<name>. The result box under the highlights updates as you type, and there is a Copy result button once you like it. Turn on the g flag to replace every match rather than only the first.
Why did only the first match get replaced?
You do not have the g (global) flag on. A replace without g stops after the first hit, which is the same rule your code follows. Click the g button and the tool will swap all of them. The match preview always shows every match regardless, so you can see how many are waiting.
Can I use named capture groups?
Yes. Write them as (?<name>...) in the pattern and reference them as $<name> in a replacement. The match list also prints each named group by its name next to the numbered groups, so you can confirm exactly what landed in each one before you trust the output.
What replacement tokens are supported?
The standard set for this engine: $1 through $99 for numbered groups, $<name> for named groups, $& for the entire match, $` for the text before the match, $' for the text after it, and $$ for a literal dollar sign. An empty replacement deletes every match, which is handy for stripping something out.
Is my test text uploaded anywhere?
No. The pattern and the text run entirely in your browser using the same engine your JavaScript already uses. Nothing is sent out, nothing is stored, and it works offline. That is why it is safe to test against real logs and real customer data. The Share button keeps your pattern and your text after the #, the part of an address no browser ever transmits, and the Embed code drops them altogether, because embed code gets pasted onto a public page.
Can I load a big log file instead of pasting?
Drop a text file directly onto the test box, or use the Load a text file link above it. The file is read locally and never leaves your machine, so you can search a real export without copying and pasting a wall of text.
Is this the same regex flavor my language uses?
It runs your pattern through the browser's own RegExp, so what you get here is exactly what JavaScript does, including named groups, lookahead and the \p{...} escapes under the u flag. The difference around lookbehind points the opposite way to the one people expect, because JavaScript accepts a variable-length lookbehind such as (?<=\d+)foo and Python's re rejects that same pattern with look-behind requires fixed-width pattern, so a green result here can still be a syntax error in your own code. Going the other way, atomic groups, possessive quantifiers, inline flags like (?i) and recursion all exist in PCRE and Python and have never existed in JavaScript, so a pattern lifted out of one of those may not compile here at all.
Can I share a pattern I built?
Use the Share button to copy a link that carries your pattern, flags, mode, test text, and replacement, so a teammate opens the exact setup you are looking at. Drop a whole log file into the test box and the text stops fitting in a URL, so the link carries the pattern and flags on their own and the page says it did that rather than handing your teammate a link that returns an error. There is also an Embed option to drop the live tool onto your own page.