Regex Portability Checker

Paste a regular expression — bare, or in JS's "/pattern/flags" form — and see exactly which parts would break, or silently behave differently, if the same pattern ran under Python's `re` module or a PCRE-family engine (PHP, Perl), and why.

Processed locally in your browser. Your file is never uploaded.

How to use this tool

  1. Paste a regex pattern, either bare ("\\d{4}-\\d{2}") or delimited ("/\\d{4}-\\d{2}/g") — nothing leaves your browser.
  2. Select "Check pattern".
  3. Review each flagged construct: whether it's an outright syntax error elsewhere, a silent behavior change, or a one-way compatibility note.
  4. Use the suggested rewrite where one is offered — some constructs (possessive quantifiers, atomic groups, recursion) have no simple mechanical JS equivalent, and those are explained instead of guessed at.

Assumptions

Sources & reference data

Methodology

The pattern body (with any "/pattern/flags" delimiters stripped) is scanned for eight specific constructs known to cause cross-language regex portability problems: Python-only named-group and named-backreference syntax, possessive quantifiers, atomic groups, the \A/\Z/\z anchors, PCRE recursive-pattern references, inline mid-pattern flags, and the ASCII-vs-Unicode default for \d/\w/\s. Each is checked with a narrow, targeted pattern match — not a general-purpose regex parser — matching how every other portability checker in this toolset works. A rewrite is only ever offered when it is mechanically, unambiguously safe.

Worked example

\A and \Z anchors

Inputs: /\Afoo.*bar\Z/

Result: JavaScript has no \A or \Z anchor at all — it silently reads \A as a literal "A" and \Z as a literal "Z", so the pattern matches something completely different rather than failing to compile. Flagged as an error precisely because it fails silently, not loudly.

Python-style named group

Inputs: (?P<year>\d{4})

Result: "(?P<year>...)" is a SyntaxError in JavaScript, which requires "(?<year>...)" without the "P". Safely rewritten by dropping the "P" — PCRE and .NET both also accept the plain form.

Possessive quantifier and atomic group

Inputs: (?>a++)b

Result: Both "(?>...)" (atomic group) and "a++" (possessive quantifier) are PCRE/Java features with no JavaScript equivalent syntax at all. Both are flagged as errors with no automatic rewrite, since an equivalent effect in JS requires restructuring the pattern with a capturing lookahead, not a text substitution.

A Python-style start anchor

Inputs: /\Afoo/

Result: Python and some other engines use `\A` for the absolute start of the string. JavaScript has no `\A` anchor: in a JavaScript pattern, the escape is not a start anchor and may be treated as an identity escape, matching `A`. The checker spots this construct in pattern text; it does not execute it against sample strings.

Practical guidance
Common mistakes

FAQs

Why is \A/\Z treated as more dangerous than the possessive-quantifier or atomic-group cases?

Possessive quantifiers and atomic groups are SyntaxErrors (or effectively so) in JavaScript — the mistake is loud and immediate. \A and \Z compile successfully and just quietly match the literal letters "A"/"Z" instead of anchoring — the mistake is invisible until the pattern misbehaves on real input.

Why does this tool suggest "(?<name>...)" for JS but flag it as a warning for Python, instead of just picking one?

Which spelling is "correct" depends entirely on which engine the pattern needs to run in — JS/PCRE/.NET want the plain form, Python requires the "P". Since this tool can't know which target actually matters to you, it reports both directions and only force-rewrites the direction that's unambiguously invalid in JS specifically (Python's "(?P<name>...)" being pasted somewhere JS will read it).

Can this tool fix a possessive quantifier or atomic group automatically?

No. An equivalent effect in JavaScript generally requires an atomic-group emulation via a capturing lookahead ("(?=(pattern))\\1"), which changes the structure of the pattern, not just its text — that's a judgment call for whoever owns the pattern, not something this tool will guess at.

Last reviewed: 2026-09-25

This is a narrow, construct-by-construct text scanner, not a regex parser or engine: it recognizes eight specific well-documented portability pitfalls and nothing else, so unusual engine-specific extensions, nested-group edge cases, and any actual matching behavior are out of scope. It never executes the pattern against sample input.

Theme and tool preferences, along with saved and recently used lists, are stored only in this browser.