Download Cheat sheet PDF 12 pages · syntax, editors, patterns, Unicode, performance, debugging
Reference April 28, 2026

Python regex vs JavaScript regex — 7 differences that matter

They look almost identical. They differ in seven specific ways that will absolutely bite you when porting code.

The summary

Feature JavaScript Python (stdlib re)
Named group syntax(?<n>...)(?P<n>...)
Named backreference\k<n>(?P=n)
Variable-width lookbehind✓ since ES2018✗ fixed-width only
String literal escapingBackslashes doubled in stringsUse raw strings r"..."
Absolute anchors \A \z
Default Unicode behaviorASCII unless /uUnicode in Python 3
Possessive quantifiers3.11+

1. Named groups have different syntax

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

The Python syntax with the P comes from the original Python regex module. Other modern engines (PCRE, .NET, JS) adopted the cleaner (?<name>...) later. PCRE supports both.

When porting Python to JS, search-replace (?P< with (?<. The flavor converter does this automatically.

2. Named backreferences are different too

JS:      \k<name>
Python:  (?P=name)

Same naming convention difference. Both flavors recognize numbered backrefs (\1, \2) identically.

3. Python's stdlib lookbehind requires fixed width

This is the biggest gotcha when porting JS regex to Python:

JS (works):       (?<=\$+)\d+
Python stdlib:    re.error: look-behind requires fixed-width pattern

Python's standard re module needs every alternative in a lookbehind to have the same length. JavaScript handles variable-width since ES2018.

Workarounds:

  • Use the third-party regex module (pip install regex)
  • Restructure: \$+(\d+) and use the capture group

4. String escaping is wildly different

In JavaScript, regex literals use slashes /.../:

const r = /\d+/;     // clean, single backslashes
const s = "\\d+";    // string form needs doubled backslashes

In Python, you almost always use raw strings:

r = re.compile(r"\d+")   # raw string — single backslash
r = re.compile("\\d+")    # without r prefix, need to double

Forgetting the r prefix in Python is a major source of bugs — "\n" in a non-raw string is a literal newline, not the regex newline metacharacter.

5. \A, \Z, \z — Python has them, JavaScript doesn't

In Python (and PCRE), you can match the absolute start or end of input regardless of multiline mode:

Python:  \A   start of string (always)
         \Z   end of string (always, or before trailing newline)
         \z   end of string (always, no exceptions)

JavaScript doesn't have these. Use ^ and $ — but be aware they match line boundaries when the m flag is on.

6. Unicode behavior differs

By default:

  • JavaScript: \d is ASCII [0-9]; add u flag for Unicode
  • Python 3: \d matches Unicode digits by default; add re.ASCII for ASCII-only

This affects which digits and letters are recognized — Arabic numerals, Devanagari digits, etc. If your text might be non-ASCII, decide which behavior you want explicitly.

7. Possessive quantifiers

Possessive quantifiers (*+, ++, ?+) eliminate backtracking. They're supported in:

  • Python: 3.11+ only
  • JavaScript: not at all (use atomic groups via lookaheads as a workaround)
  • PCRE / Java / Ruby: always

Beyond the basics

A few subtler differences:

  • Replacement syntax: JS uses $1, Python uses \1 (or \g<name>)
  • Compilation: Python explicitly compiles (re.compile); JS compiles lazily on use
  • Sticky flag: JS has the y flag for sticky matching at lastIndex; Python doesn't
  • matchAll: JS has matchAll; Python has finditer (similar idea)

The takeaway

The two flavors look almost identical and disagree in small but important ways. When porting a regex, watch especially for: named group syntax, lookbehind width restrictions, raw-string usage, and Unicode behavior.

If you regularly move regex between Python and JavaScript, bookmark the flavor converter — it handles the syntactic differences automatically and flags features that don't carry over.


Related reading


Try this pattern in the explainer

Paste any regex into the live explainer and see what each token means, with example matches in real time.

Open the regex explainer →