Test regex patterns with real offsets, every capture group with its own position, all eight flags including v and y, an explanation that reads the pattern rather than guessing, and a runaway pattern stopped instead of freezing the page
Initializing in your browser…
Test XPath 1.0 against XML with all four result types, not just node-sets, and the namespaces your document declares bound for you including the default one
Convert text between 17 cases with every rule stated: punctuation is a separator, acronyms survive, accents survive a URL slug, and Title Case follows a style you name (Chicago, AP or APA) rather than an unattributed word list
Count words, characters, sentences and paragraphs with every rule stated: characters as a reader sees them rather than as UTF-16 code units, sentences that know Dr. from the end of one, and six readability formulas each shown with the paper it comes from
You wrote a pattern to pull order IDs from log lines and need to confirm it matches the real format and captures the number.
Pattern + test string
/order-(?<id>\d{4,})/g on "ok order-10473 then order-9 fail"Matches, with offsets
Match 1 3 to 14 "order-10473"
group 1 (id) 9 to 14 "10473"
"order-9" is not matched: {4,} needs four digits or more.Every match carries the offset it was found at, and every capture group carries its own, so you can see exactly where a group boundary fell rather than guessing from the text. The explanation panel reads the pattern rather than searching it for substrings, so a dot inside a character class is not described as the any-character class and an escaped plus is not described as a quantifier. A pattern that cannot be compiled is reported with the engine own message and, where there is one, a next step: nothing being searched is not the same as nothing matching. And a runaway pattern is stopped: (a+)+$ against thirty-four a characters and one that does not match had not finished after 164 seconds when it was measured, so the match runs in a worker this page can terminate after five.
Regex flavors are not interchangeable. The pattern that works in your text editor may fail in your code because JavaScript, PCRE (used by PHP, Perl, and grep -P), Python's re module, .NET regex, and POSIX BRE/ERE implement subtly different features. Lookbehind assertions work in JavaScript (ES2018+), Python, and .NET but not in Ruby or older Safari. Possessive quantifiers (a++) exist in PCRE and Java but not in JavaScript. Named capture groups use different syntax across flavors: (?P<name>...) in Python, (?<name>...) in JavaScript and .NET, and (?P<name>...) or (?<name>...) in PCRE depending on version. This tester runs the JavaScript (ECMAScript) regex engine, which is what the browser and Node.js use, so the results here match production behavior in any JavaScript-based system. Beyond flavor differences, the most dangerous pitfall in regex is catastrophic backtracking. A pattern like `(a+)+b` matching against `aaaaaaaaaaaaaaaaaaaaaac` takes exponential time because the engine tries every possible way to split the a's between the inner and outer groups. Real-world examples brought down Cloudflare in 2019 and Stack Overflow in 2016. This tester runs the match in a Web Worker with a five second deadline, which is the only thing that actually stops a runaway pattern: a regular expression cannot be interrupted once it starts, so a tool that runs one on the main thread has no way back. Measured in node on 2026-09-03, `(a+)+$` against thirty `a` characters and one that does not match took 82 seconds, and against thirty-four it took 164 and was still going. Here it comes back within five seconds with a message saying it was stopped and what usually causes it.
The tester evaluates your regex with every keystroke, showing every match at its real offset with every capture group and its own position. All eight flags are offered: `g` makes a pattern stateful (lastIndex advances between matches, which matters when you reuse a RegExp object), `i` matches without regard to case using a full Unicode fold when `u` or `v` is also set, `m` makes `^` and `$` match at line boundaries as well as at the ends of the text, `s` makes `.` match a newline, `u` treats the pattern and the text as code points rather than UTF-16 code units and enables `\p{...}` property escapes, `v` adds set operations inside a character class and cannot be combined with `u`, and `y` matches only at lastIndex. The `d` flag is turned on for you and is not offered as a switch, because it is how the group offsets are known and it changes nothing about what matches. The `v` and `y` flags were not offered at all before this pass, and the descriptions for the others were three words each.
Capture groups come in three forms. Numbered groups `(...)` are the classic form, referenced by `$1``$2`etc. in replacements. Named groups `(?<name>...)` are referenced by `$<name>` and make complex patterns dramatically more readable, a date-parsing regex using named groups like `(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})` is far clearer than one relying on position alone. Non-capturing groups `(?:...)` group atoms for quantifiers without allocating a capture slot, which matters for performance on patterns used in tight loops. The tester displays each capture group separately with the captured substring and its position, making it easy to verify that group boundaries are where you expect.
Common patterns that trip up regex writers: matching email addresses is famously harder than it looks (the RFC 5322 grammar for valid email is about 6,400 characters as a regex, so most validators use a simplified approximation that accepts some invalid addresses and rejects some valid ones). Matching URLs has the same problem plus the complication of internationalized domain names. Matching HTML with regex is actively harmful because HTML is not a regular language, use a real parser. For CSV parsing, regex can handle simple cases but falls over on embedded commas, quoted strings, and multiline fields, so use a CSV library. The tester is best used for validating specific field formats where the grammar is actually regular: phone numbers, postal codes, semver strings, hex color codes, and log-line patterns where the source format guarantees regularity.
Build and test regex patterns for email addresses, phone numbers, URLs, or custom input formats before embedding them in your code.
Craft patterns to extract timestamps, error codes, or IP addresses from log entries, verifying matches against sample lines.
Test complex find-and-replace patterns with capture groups before running them across a codebase or document.
Experiment with regex syntax and instantly see what matches, a much faster feedback loop than modifying and re-running scripts.
Pattern: ^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$, matches standard email addresses.
Pattern: (\d{4})-(\d{2})-(\d{2}), captures year, month, and day from ISO dates.
The JavaScript (ECMAScript) engine, which is what runs in every modern browser and in Node.js. The match itself runs in a Web Worker so it can be stopped; the answers are the same engine as your production code, one thread away.
Check the message above the results. If the pattern cannot be compiled with the flags you have on, nothing was searched at all, which is not the same as nothing matching, and the tool says which it is. The commonest cause is the u flag: an escape the grammar does not recognise is a syntax error under u and just the character without it, so a\-b is fine by default and refused with u on.
It was still running after five seconds. A pattern with a quantifier inside a quantifier, like (a+)+ or (a|a)*, can take exponentially long on text that nearly matches: measured here, (a+)+$ against thirty a characters and one that does not match took 82 seconds, and against thirty-four it took 164 and had not finished. A regular expression cannot be interrupted once it starts, so the match runs in a worker this page can terminate. Making the inner part unambiguous, or anchoring it, usually fixes the pattern.
Exactly as typed inserts the characters you wrote, so $1 is a dollar sign and a one. With $ patterns, ECMA-262 22.1.3.19 applies: $& is the whole match, $1 to $99 are the groups, $<name> is a named group, $` and $’ are the text before and after, and $$ is a dollar sign. Both are useful and neither is a safe default to impose, so it is a switch.
Most basic patterns are cross-compatible. However, features like lookbehinds, possessive quantifiers, or atomic groups may differ between engines. This tool reflects JavaScript behavior.
g = match all occurrences (not just the first), i = case-insensitive, m = ^ and $ match line boundaries, s = dot matches newlines, u = full Unicode matching.
Your text is processed locally in the browser. Nothing you paste or open is transmitted or logged.