How to test a regular expression
- Type your pattern into the first field, without the surrounding slashes.
- Set the flags. Leave g on to find every match rather than just the first.
- Paste the text you want to match against into the test box.
- Watch the highlighting and the match count update as you type.
- Add a replacement string to preview what a substitution would produce.
What this tester shows
- Every match highlighted in place, so you can see what the pattern actually caught.
- A live match count, which immediately reveals a pattern that is too greedy or too strict.
- Numbered capture groups listed per match, with unmatched optional groups marked.
- Named groups shown by name when the pattern uses them.
- A replacement preview supporting $1, $2 and $& substitutions.
- Clear error messages when a pattern will not compile, rather than silent failure.
Why testing beats reasoning
Regular expressions are notoriously hard to read and easy to get subtly wrong. A pattern that looks correct matches one case too many; a pattern that looks strict misses an edge case that appears once in a thousand records. Reasoning about them in your head is unreliable even for people who write them daily.
Testing against real text removes the guesswork. If the pattern is too greedy, the highlighting shows one enormous match instead of several small ones. If it is too strict, the count says zero. Both are obvious in a second and invisible in code.
The flags, and why g matters most
- g: find every match. Without it only the first is returned, which is the commonest source of "my regex only works once".
- i: case insensitive.
- m: makes
^and$match at each line rather than only at the start and end of the whole text. - s: lets
.match a newline, which it does not by default. - u: proper Unicode handling, needed for
\p{...}property escapes and astral characters.
Greedy versus lazy
This is the single most common mistake. Quantifiers such as * and + are greedy: they match as much as possible and then give back only as much as they must. Apply <.+> to <a>text</b> and it matches the entire string, not the first tag, because .+ swallowed everything and the final > still found a home.
Adding a question mark makes a quantifier lazy, <.+?> stops at the first >. The highlighting on this page makes the difference immediately visible, which is why testing catches it and reading rarely does.
Capture groups and replacements
Parentheses capture. Each group is numbered from one in the order its opening bracket appears, and this tester lists them for every match, marking optional groups that did not participate. Named groups written as (?<year>\d{4}) are shown by name, which is far more readable than counting brackets in a long pattern.
The replacement field previews a substitution. Use $1 and $2 to insert captured groups, $& for the whole match, and $<name> for a named group. Seeing the result before running it on real data is the point.
This is the JavaScript engine
Regular expression syntax varies between languages more than people expect. Lookbehind needs a recent browser and is unsupported in some other engines. Possessive quantifiers and atomic groups exist in PCRE and not here. Named groups use (?<name>) in JavaScript and (?P<name>) in Python.
A pattern that works here will work in JavaScript. Test it in the target language before relying on it elsewhere. One more caution: some patterns with nested quantifiers can take exponential time on certain inputs. A phenomenon called catastrophic backtracking, so if the page becomes unresponsive on a long string, simplify the nesting rather than the input. Everything runs in your browser, so log extracts and customer data used as test text are never uploaded.