Regex Tester
Test JavaScript regular expressions live with highlighted matches and replace preview.
- #1 @14jane@example.com
- #2 @34john@test.io
Contact me at [redacted] or [redacted] for details.
How to use
- Enter a regex pattern (without delimiters).
- Toggle flags: g (global), i (case-insensitive), m (multiline), s (dotall), u (unicode).
- Type or paste a test string — matches highlight as you type.
- Provide a replacement string to preview the result.
About this tool
ShowHide
Write a pattern, toggle the flags, and every match lights up in the test string as you type. Capture groups are listed per match and a replacement preview runs alongside, so you can confirm both what the pattern finds and what it would produce. The engine is the browser's own JavaScript RegExp, which means what you see is exactly what your code will do — and nothing leaves the page, which matters when the sample you are debugging is real data.
Being the real JavaScript engine also means inheriting its specific personality. \d matches only the ASCII digits 0 through 9, so a string of Arabic-Indic numerals fails a pattern that looks like it should accept any digits; \p{Nd} with the u flag is the one that does. The dot skips newlines unless you set the s flag. There is no \A or \z — anchoring to the whole string means ^ and $ without m. Lookbehind works in current browsers but arrived late, so a pattern using it may fail on an older device even though it passes here.
Portability is worth checking before you copy a pattern into another language. Go's standard library uses RE2, which has no backreferences and no lookaround at all, by design — a pattern that works perfectly here will simply be rejected there. Python and PCRE accept more than JavaScript does, including atomic groups and possessive quantifiers, so a pattern copied the other way may silently behave differently rather than erroring.
The failure mode to actually fear is catastrophic backtracking. A pattern with nested quantifiers over overlapping alternatives can take exponential time on input that nearly matches: /^(a+)+b$/ tested against twenty-eight a characters followed by an x takes seconds in this engine, and each extra character roughly doubles it. On a server that is a denial of service from a single short request, which is why the pattern class has its own name. If your regex has a quantifier inside a quantifier, try it against a long near-miss before shipping it — this page is a good place to find out.
Frequently asked questions
What dialect does this use?
JavaScript regex (ECMAScript). Lookbehinds, named groups, and Unicode property escapes are supported in modern browsers.
How do I reference capture groups in the replacement?
Use $1, $2, $& for the full match, or $<name> for named groups.
Is there a match limit?
The first 10,000 iterations are captured to keep the UI responsive; the first 50 are shown in the match list.
Is my data sent anywhere?
No. Patterns and test strings run only in your browser, and the auto-save keeps them in your local storage.
Why does my pattern freeze the page?
Almost certainly catastrophic backtracking. Patterns that nest quantifiers - something like (a+)+b - can force the engine through an exponential number of ways to split the input before admitting there is no match. The fix is to make the inner parts unambiguous, usually by replacing a greedy .* with a negated character class that cannot overlap the delimiter.
What does the global flag actually change?
Without g, matching stops at the first result. With g, the search continues through the string, which is what makes the match list longer than one - and it also makes the regular expression stateful in real code, because it remembers where it stopped. That is the usual reason a pattern reused in a loop appears to skip every other match.
How do I match across multiple lines?
Two different flags are involved and they are easy to confuse. Multiline changes what the anchors mean, so ^ and $ match at every line break instead of only at the ends of the string. Dot-all changes what the dot matches, letting it cover newlines too. If a pattern stops at the end of the first line, dot-all is usually the one you wanted.
Guides on this topic
Related tools
Glob Pattern Tester
Test file paths against a glob pattern (*, **, ?, [...], {a,b}) in your browser.
Developer
Find & Replace
Find and replace across a block of text. Optional regex with global, case-insensitive, multiline, and dotAll flags. Live match count.
Text
String Escape Converter
Escape a string for 10 contexts at once — JavaScript, JSON, HTML entities, URL, SQL, regex, Bash (single/double quote), C string, Unicode \u escapes.
Developer
Math Expression Evaluator
Evaluate arithmetic expressions with the usual math functions — sqrt, sin, log, pow, min/max, and constants pi, e, tau.
Math & Statistics
CSS Selector Tester
Test a CSS selector against your HTML and see exactly which elements it matches, in your browser.
Developer
.gitignore Tester
Paste a .gitignore and a list of paths to see which are ignored and exactly which line decided — the answer git check-ignore -v gives.
Developer
Cron Expression Explainer
Translate a cron expression into plain English (or your language) and break down each field.
Developer