Why Does My Regex Work in Python but Fail in JavaScript?
Short answer: the engines disagree on shorthand classes. Python regex is Unicode-aware out of the box; JavaScript defaults to ASCII and needs the u flag to catch up. That single difference explains most cross-language surprises.
Why would the same pattern behave differently?
Because the two engines disagree on what the shorthand classes mean. Python treats \d, \w, \s as Unicode-aware by default; JavaScript keeps them ASCII-only unless you add the u flag. The same string can match in one and fail in the other.
What exactly does \d match in each language?
In Python, \d matches any Unicode decimal digit, so Arabic-Indic and Devanagari digits match. In JavaScript without the u flag, \d is ASCII-only: 0-9. With the u flag, it becomes Unicode-aware and agrees with Python.
What about \w and word boundaries?
# Python: \d works as a Unicode digit
re.search(r"\d", "١٢٣") # matches
re.search(r"\bword\b", "word") # matches// JavaScript: \d is ASCII-only unless the u flag is on
/\d/.test("١٢٣"); // false
/\bword\b/u.test("word"); // true Python's \w includes Unicode letters, and \b respects them. JavaScript's \b without u only sees ASCII letters, so boundaries around accented or CJK text behave differently.Why is the u flag such a big deal?
The u flag switches the JavaScript engine into Unicode mode. It changes \d, \w, \s, \b, and how quantifiers treat astral characters like emoji, which are two code units without it.
Are there syntax differences beyond character classes?
Yes. Lookbehind works in both now, but JavaScript requires lookbehinds to be fixed-length; Python allows variable-length. Named groups use (?P
How do I write a pattern that behaves the same in both?
Avoid engine-specific shorthands. Use explicit classes like [0-9] and [a-zA-Z] when you want ASCII, or [\p{L}] with the u flag when you want Unicode letters. Test the same string against both engines before shipping.
What is the fastest way to compare engines?
Run the pattern against a small test set in both. The regex tester shows matches, groups, and flags side by side, so differences surface before they reach production.
Is there a checklist for porting a regex?
Check five things: \d/\w/\s behavior, word boundaries, lookbehind length, named group syntax, and whether flags like i or m do the same. If the pattern passes those on both engines, it is portable.