Flavor cheat sheet: the same regex in seven engines
Regular expressions are a family of dialects, not one language — the pattern that works in your code review may fail here, or vice versa, for reasons that have nothing to do with your logic. This chart covers the differences that actually bite. The live engine on this page is JavaScript; read your language's column before copying a pattern across.
| Feature | JavaScript | Python (re) | Java | C# / .NET | Go (RE2) | PHP (PCRE) | POSIX ERE |
|---|---|---|---|---|---|---|---|
| Lookbehind (?<=…) | Yes (variable-length) | Fixed-width only | Bounded-width | Yes (variable) | No | Fixed-width branches | No |
| \d matches non-ASCII digits? | No — ASCII 0–9 only, even with u | Yes by default on str (use re.ASCII to restrict) | No, unless UNICODE_CHARACTER_CLASS | Yes by default | No — ASCII only | No by default (/u + UCP changes it) | Use [[:digit:]] |
| Named group syntax | (?<name>…) | (?P<name>…) | (?<name>…) | (?<name>…) or (?'name'…) | (?P<name>…) | Both styles | None |
| Backreferences \1 | Yes | Yes | Yes | Yes | No (by design) | Yes | Not in ERE |
| Inline flags (?i) | No — flags go after the closing / | Yes | Yes | Yes | Yes | Yes | No |
| Possessive / atomic groups | No | 3.11+ only | Yes | Atomic (?>…) | N/A (never backtracks) | Yes | No |
| Can it blow up (backtracking)? | Yes | Yes | Yes | Yes (timeout API available) | No — linear time, guaranteed | Yes (has limits) | Depends on implementation |
Two practical takeaways. First, if a pattern must run on untrusted input at scale, Go's RE2 semantics (also available as libraries elsewhere) are the only ones that guarantee no catastrophic backtracking — the trade being no backreferences or lookaround. Second, the most common porting failures are mundane: Python's (?P<name>) syntax rejected by JavaScript, an inline (?i) flag that JavaScript doesn't accept, or a \d that suddenly matches ٣ and 4 when the pattern moves to Python.
How the highlighting and groups work
The tester compiles your pattern with the browser's own RegExp, runs it against the test text, and walks the matches. With the g flag on, every match is found; off, only the first. Each numbered group is whatever its parentheses captured (or no match if that branch didn't participate), and named groups — (?<year>\d{4}) — appear under their names. The replace preview uses JavaScript's String.replace semantics: $1 for numbered groups, $<name> for named ones, $& for the whole match, and $$ for a literal dollar sign.
Frequently asked questions
My pattern works in Python — why not here?
Almost always one of four dialect differences. Python's named groups are (?P<name>…); JavaScript requires (?<name>…) without the P. Python accepts inline flags like (?i) anywhere; JavaScript takes flags only as the checkboxes here. Python's \A and \Z anchors don't exist in JavaScript (use ^ and $ without the m flag). And a pattern written with re.VERBOSE whitespace will match literal spaces here. The chart above covers the rest.
What is catastrophic backtracking, and what does the guard here do?
Patterns like (a+)+$ against a long string of a's followed by a b force the engine to try exponentially many ways of dividing the a's before concluding there's no match — seconds, then minutes, of CPU. It's the mechanism behind real-world ReDoS outages. This page runs every match inside a Web Worker with a 1.5-second timeout: a pathological pattern gets cancelled with a warning instead of freezing your tab, so you can experiment freely. The fix in your code is to remove nested quantifiers over overlapping character sets, anchor the pattern, or use a linear-time engine (see the Go column above).
Is the text I paste sent anywhere?
No. Compilation and matching happen in your browser — no server, no analytics on your pattern or text, and the page keeps working offline once loaded. Log excerpts and real emails are exactly the things you shouldn't paste into a random server-side tester.
Why does the email pattern reject some valid addresses?
Because every short email regex is a pragmatic approximation. The full grammar (RFC 5322) permits quoted local parts, comments, and other constructs no signup form wants; a regex that accepted them all would be pages long and still wrong about deliverability. The library pattern here checks the shape — something, @, something, dot, something — which is the right level for input validation. The only true validation is sending mail to it.