Regex Tester
Test regular expressions with live highlighting, matches and capture groups.
Reviewed by Aygul Dovletova · Last reviewed
How to Use the Regex Tester
- Type your pattern into the Pattern field without surrounding slashes. For example, enter
\\b\\d{3}-\\d{4}\\b, not/\\b\\d{3}-\\d{4}\\b/g. - Toggle the flags you need from the checkbox row:
gfor all matches,ifor case-insensitive,mfor multiline anchors,sfor dot-matches-newline,ufor Unicode,yfor sticky. - Paste your test text into the large Subject area. The highlighter runs on every keystroke so you get immediate feedback.
- Inspect the match list below the textarea. Each entry shows the match index, the matched substring, and any numbered or named capture groups.
- Open the cheat sheet if you need a reminder of quantifier syntax, anchors, character classes, or lookaround constructs.
- Copy a pattern using the copy button if you want to drop it into your code as a literal or
new RegExp().
Under the Hood
Your pattern is compiled via new RegExp(pattern, flags), which hands it to the same engine your JavaScript code uses at runtime - V8's Irregexp in Chrome and Node, SpiderMonkey's regexp engine in Firefox, or JavaScriptCore's YARR in Safari. When you type, a try/catch block catches SyntaxError and shows it inline instead of throwing. Matching uses String.prototype.matchAll so you get the full list of matches together with groups, indexes, and input length without having to run the regex in a loop. The highlighter walks the match array once and splices <mark> spans into the DOM via a safe text-node approach, so special characters in your subject are never treated as HTML.
When You Would Use It
- Prototyping a validation pattern for an email, phone, or invoice number before you paste it into your Zod, Joi, or Yup schema.
- Debugging a regex that works in your IDE but behaves differently in production because of a subtle flag mismatch.
- Extracting structured data from log lines - timestamps, IPs, request IDs - and verifying the capture groups land where you expect.
- Teaching someone the difference between greedy and lazy quantifiers by toggling
.*versus.*?over the same input. - Converting a
grep -Ecommand into a JavaScript regex and confirming the semantics survive the translation.
Common Pitfalls and Edge Cases
- ECMAScript is not PCRE. Patterns that rely on possessive quantifiers, subroutine calls, or conditional groups will not compile; these come from PCRE/Perl and have no ECMAScript equivalent.
- Lookbehind support. Variable-length lookbehind like
(?<=foo.*)is supported in modern V8, SpiderMonkey, and JavaScriptCore, but fails in older Safari builds. If you target pre-2020 browsers, avoid it. - Unicode property escapes such as
\\p{L}only work when theuflag is set. Forgetting it produces an invalid-escape error. - Surrogate pairs. Without the
uflag a single emoji is two code units and.only matches the first half. - The global flag and
lastIndex. Reusing the sameRegExpobject withgand.test()advanceslastIndexbetween calls, which is a classic source of "why does my validator alternate true/false" bugs. - Catastrophic backtracking. Patterns like
(a+)+$against a long non-matching input can freeze the tab. If the highlighter hangs, your pattern is almost certainly quadratic or worse.
Regex Syntax Background
The ECMAScript regular expression grammar is specified in Annex B and section 22.2 of the ECMA-262 standard. It draws heavily from Perl and PCRE but diverges in places: no embedded modifiers with (?i), no named atomic groups, limited Unicode support without the u flag, and distinct semantics for $ at the end of a string when m is off. Other regex flavors in common use include PCRE (PHP, nginx), Python's re and regex modules, Go's RE2 (linear time, no backtracking), and POSIX ERE as implemented by grep -E. RE2 deserves special mention: it rejects backreferences and lookaround but guarantees linear-time matching, which is why Google uses it for user-supplied patterns.
Comparison to Alternatives
For complex test suites that need to be version-controlled with your codebase, regex101.com offers permalinks and a per-pattern debugger that steps through each token - extremely useful when you are truly stuck. grep -P, ripgrep, and sed -E remain the fastest way to search a large code base from the terminal, and ripgrep's Rust regex engine is PCRE-compatible but runs in guaranteed linear time. Your IDE's Find-in-files is perfect when you want to couple a regex with context and replace across many files. Use this web tester when you need to nail down one ECMAScript-specific pattern, avoid installing anything, and see per-match capture groups at a glance - especially because the engine here is exactly the one your Node.js service or browser code will use.
Frequently Asked Questions
Is this the same regex engine as my Node.js service?
If your Node.js runtime is V8-based (which is all mainstream Node builds) then yes - the engine is Irregexp, the same one this page uses when you are in Chrome. Safari and Firefox use different engines with near-identical semantics for common patterns, so patterns tested here are portable to any modern JS runtime. Differences appear at the edges: lookbehind support, Unicode property escapes, and the not-yet-universal v flag (RegExp v).
Why does my pattern match in regex101 but not here?
regex101 defaults to PCRE2 (in the PCRE2 tab), which supports features ECMAScript lacks: possessive quantifiers, atomic groups, conditional patterns, recursion, and inline modifiers such as (?i). Switch regex101 to its ECMAScript / JavaScript flavor to reproduce this tester's behavior. The reverse also happens: ECMAScript requires the u flag for \p{Letter} and similar property escapes, while PCRE treats them as always available.
Does my pattern or test string ever leave the browser?
No. The RegExp constructor is synchronous and lives entirely in the V8, SpiderMonkey, or JavaScriptCore engine embedded in your browser. No fetch request ships your pattern anywhere, no websocket is open, and there is no analytics hook receiving your subject text. You can disable the network after the page loads and the tester keeps working, which is the simplest way to prove local processing.
How do I reference a capture group in the replacement?
In a replacement string you reference numbered groups with dollar-number, for example $1 for the first group, $2 for the second. Named groups use the form $<name>. The whole match is $&, the text before the match is $`, and the text after is $'. In a replacement function (String.prototype.replace with a callback) you get groups passed as positional arguments and the named groups object as the last argument.
Why does .* sometimes match too little or too much?
The dot metacharacter does not match newline by default. On multi-line input it stops at each \n, which can look like it is matching too little. Add the s flag (dotAll) to make . also cross line breaks. Conversely, .* is greedy and consumes as much as possible before backtracking; switch to .*? for a lazy match that stops at the first opportunity. Combining s with a greedy .* across an entire document is a famous performance trap.
What is the u flag actually doing?
Setting the u flag switches the pattern into Unicode mode as defined in ECMAScript. Three things change: . matches a Unicode code point instead of a UTF-16 code unit, so emojis and supplementary-plane characters match as one; \p{Script=Cyrillic} and similar property escapes become available; and escape sequences that do not correspond to any defined escape throw a SyntaxError instead of silently matching the literal character. For any modern internationalized input, always set u.
Can I use this to build a parser for JSON or HTML?
You can, but you should not. JSON is context-free (nested braces and brackets) and HTML is even more complex; regex is a regular language in the Chomsky sense and cannot balance recursive structures correctly. You will get something that works on your sample and breaks on real-world input. For JSON use JSON.parse; for HTML use DOMParser or a proper parser like parse5. Regex is the right tool for scanning flat patterns within already-tokenized input.
How do I tell if my regex will backtrack catastrophically?
Look for nested quantifiers where the inner pattern overlaps, such as (a+)+, (a|a)+, or (a*)* followed by something that can fail at the end. On a long input of a-characters followed by a non-matching terminator, the engine explores exponentially many ways to split the a's. Rewrite with a single quantifier or use atomic grouping in flavors that support it. RE2 and ripgrep avoid the problem entirely by rejecting backreferences and lookaround.
Is sticky mode useful in real code?
Yes, when you are writing a tokenizer or lexer. Setting the y flag makes the regex match only at the exact lastIndex, so you can advance through a string one token at a time without scanning ahead. Babel, TypeScript, and Prettier all use sticky-mode regex in their lexers. For one-off validation or extraction, stick with g or no flag.
How do I write a multiline regex that is still readable?
ECMAScript does not have PCRE's extended-mode x flag, so you cannot embed comments and whitespace inside a pattern literal. Instead, build the pattern programmatically from tagged templates or concatenated strings and pass the result to new RegExp. Libraries such as XRegExp add named groups, free-spacing, and inline comments on top of the native engine if you need them.
More Developer Tools
Base64 Encoder & Decoder
Encode UTF-8 text to Base64 online or decode Base64 back to UTF-8 and plain text. Runs in your browser with no upload.
Open toolBulk URL Encode / Decode
Encode or decode many URLs at once. Paste a newline-separated list and the tool processes each line in parallel, preserving order and blank lines.
Open toolCode Screenshot
Create beautiful code snippet images with customizable themes.
Open toolColor Converter
Convert colors between HEX, RGB, HSL and CMYK formats.
Open toolCron Expression Parser
Parse cron expressions into human-readable schedules with next run times.
Open toolCSS Formatter / Minifier
Format, beautify and minify CSS code.
Open tool