Die größte Falle bei JavaScript vs. Python Regex ist, dass die beiden Engines den Großteil der gleichen Syntax teilen, sodass ein Muster portabel aussieht, bis es sich stillschweigend falsch verhält. JavaScript verwendet den ECMAScript-Dialekt; Python verwendet seinen eigenen re-Modul-Dialekt, der näher an PCRE ist. Sie stimmen in den üblichen 80% überein, weichen dann aber bei Ankern, Lookbehind, Ersetzungsstrings und Unicode ab. Dieser Leitfaden listet jeden Unterschied auf, der tatsächlich Code bricht, damit Sie Muster schreiben können, die das Kopieren und Einfügen zwischen den Sprachen überleben.
Wenn Sie jemals einen Regex von Stack Overflow übernommen haben und gesehen haben, dass er in einer Laufzeitumgebung matcht, aber in der anderen einen Fehler wirft oder nichts zurückgibt, dann ist das der Grund: Die Antwort wurde für eine Engine geschrieben. Unten finden Sie die vollständige Karte mit Beispielen und einer schnellen Möglichkeit, dasselbe Muster in beiden Dialekten zu testen, bevor Sie es ausliefern.
JavaScript vs Python Regex auf einen Blick#
Hier die Kurzfassung vor dem tiefen Eintauchen. Dies sind die Unterschiede, die echte Fehler verursachen, keine Kleinigkeiten.
| Funktion | JavaScript (ECMAScript) | Python (re) |
|---|---|---|
| Zeichenkettenanfang/-ende Anker | Keine (nur ^/$) | \A und \Z |
| Lookbehind | Fest und variabel (ES2018+) | Nur feste Länge |
Besitzergreifende Quantoren (a++) | Nicht unterstützt | Unterstützt (Python 3.11+) |
Atomare Gruppen (?>...) | Nicht unterstützt | Unterstützt (Python 3.11+) |
| Benannte Gruppensyntax | (?<name>...) | (?P<name>...) |
| Benannter Rückverweis | \k<name> | (?P=name) |
| Ersetzungsgruppenreferenz | $1, $<name> | \1, \g<name> |
.-matcht-Zeilenumbruch-Flag | s (dotall) | re.DOTALL / re.S |
Unicode-Eigenschafts-Escapes \p{...} | Benötigt u- oder v-Flag | Nicht eingebaut (regex-Modul verwenden) |
Inline-Flags (?i) | Nicht unterstützt | Unterstützt |
| Standard-Unicode-Behandlung | UTF-16-Code-Einheiten | Unicode standardmäßig in re |
Der Rest dieses Artikels erklärt jede Zeile, warum sie wichtig ist und wie man ein Muster umschreibt, damit es in beiden Sprachen funktioniert.
Kurzer Tipp: Wenn ein Muster in einer Sprache funktioniert und in der anderen nicht, liegt die Ursache fast immer an Ankern, Lookbehind oder Ersetzungssyntax. Prüfen Sie diese drei zuerst, bevor Sie annehmen, dass der Regex selbst falsch ist.
Anker: die Lücke zwischen \A und \Z#
Dies ist die häufigste Ursache für „funktioniert in Python, bricht in JavaScript“-Fehler. Python unterstützt zwei Ankersets, JavaScript nur eines.
In Python passen ^ und $ auf den Anfang und das Ende jeder Zeile, wenn das re.MULTILINE-Flag gesetzt ist, während \A und \Z unabhängig von Flags immer nur den absoluten Anfang und das Ende der gesamten Zeichenkette matchen. Diese Unterscheidung ermöglicht es, einen strengen Ganzzeichenketten-Validator zu schreiben, der das Multiline-Verhalten ignoriert.
JavaScript hat kein \A oder \Z. Es bietet nur ^ und $, deren Bedeutung sich je nach m-Flag (Multiline) ändert. Ein Python-Muster wie \A\d{4}\Z hat daher kein direktes JavaScript-Äquivalent.
// Python: re.match(r"\A\d{4}\Z", text)
// JavaScript-Äquivalent (ohne Multiline-Flag, daher ^ und $ für gesamte Zeichenkette):
/^\d{4}$/.test(text);
Die Lösung: Das m-Flag in JavaScript weglassen und auf einfache ^/$ setzen, die dann die gesamte Zeichenkette verankern. Der Haken: JavaScripts $ kann auch direkt vor einem abschließenden Zeilenumbruch matchen, daher für echte End-of-String-Strenge $(?![\s\S]) verwenden. Wer dies vergisst, riskiert, dass mehrzeilige Eingaben einen scheinbar wasserdichten Validator umgehen.
Lookbehind: Feste vs. variable Breite#
Lookbehind ist der Bereich, in dem die beiden Engines ihre Stärken tauschen, was viele überrascht, die annehmen, Python sei immer die leistungsfähigere Engine.
- JavaScript hat Lookbehind in ES2018 eingeführt und unterstützt sowohl feste als auch variable Längen.
(?<=\$\d+)und(?<=cat|elephant)funktionieren beide. - Pythons integriertes
re-Modul unterstützt nur Lookbehind mit fester Breite.(?<=cat|dog)funktioniert, weil beide Alternativen drei Buchstaben lang sind, aber(?<=cat|elephant)löstre.error: look-behind requires fixed-width patternaus.
Ein Lookbehind mit variabler Länge, der in einem modernen Browser einwandfrei läuft, führt in Python zu einem Kompilierungsfehler. Wenn Sie in Python variable Lookbehinds benötigen, installieren Sie das Drittanbieter-Modul regex, das dies unterstützt, oder strukturieren Sie das Muster um, indem Sie anstelle eines Lookbehinds eine Erfassungsgruppe verwenden.
# Scheitert in Pythons re:
re.compile(r"(?<=USD |EUR )\d+") # unterschiedliche Längen -> Fehler
# Workaround: Erfassen und referenzieren oder Alternativen auf gleiche Breite bringen
re.compile(r"(?:USD|EUR) (\d+)") # erfasst die Zahl in Gruppe 1
Wenn Sie noch unsicher sind, wie Lookbehind und Lookahead tatsächlich funktionieren, lohnt es sich, die tieferen Mechanismen in unserem Regex-Lookahead-und-Lookbehind-Leitfaden nachzulesen, bevor Sie Muster zwischen Sprachen portieren.
Syntax für Capture Groups und Backreferences#
Beide Engines unterstützen benannte Gruppen, aber die Syntax unterscheidet sich, was zu einem harten Kompilierungsfehler und nicht zu einer stillen Nichtübereinstimmung führt.
JavaScript verwendet (?<name>...). Python verwendet (?P<name>...) mit dem zusätzlichen P. Wenn man sie verwechselt, lässt sich das Muster einfach nicht kompilieren.
| Aktion | JavaScript | Python |
|---|---|---|
| Benannte Gruppe definieren | (?<year>\d{4}) | (?P<year>\d{4}) |
| Backreference innerhalb des Musters | \k<year> | (?P=year) oder \1 |
| Nummerierte Backreference | \1 | \1 |
Nummerierte Backreferences (\1, \2) sind in beiden identisch, daher sind sie die sicherste Wahl, wenn ein Muster-String unverändert in beiden Sprachen laufen soll. Sobald man zu benannten Gruppen greift, muss man das Muster pro Engine verzweigen.
Inline-Flags#
Python erlaubt es, Flags innerhalb des Musters mit (?i) für Groß-/Kleinschreibung, (?m) für mehrzeilig usw. zu setzen, einschließlich der bereichsbezogenen Form (?i:...). JavaScript unterstützte historisch keine Inline-Flag-Modifikatoren; Flags wurden nur auf dem Literal (/pattern/i) oder dem RegExp-Konstruktor gesetzt. Bereichsbezogene Inline-Modifikatoren (?i:...) sind eine neuere ECMAScript-Erweiterung und noch nicht universell in allen Laufzeiten verfügbar, daher sollte man sich für portablen Code nicht darauf verlassen.
Ersatzzeichenfolgen-Syntax (der stille Fehler)#
Dieser Fehler ist gefährlich, weil er keine Ausnahme auslöst. Er produziert einfach falsche Ausgaben, die bei der Überprüfung viel schwerer zu finden sind als ein Absturz.
Wenn Sie eine erfasste Gruppe in einer Ersatzzeichenfolge referenzieren, verwendet JavaScript das Dollarzeichen und Python einen Backslash.
// JavaScript: $1 referenziert Gruppe 1, $<name> referenziert eine benannte Gruppe
"2026-06-25".replace(/(\d{4})-(\d{2})/, "$2/$1"); // "06/2026-25"
# Python: \1 referenziert Gruppe 1, \g<name> referenziert eine benannte Gruppe
re.sub(r"(\d{4})-(\d{2})", r"\2/\1", "2026-06-25") # "06/2026-25"
Wenn Sie eine JavaScript-Ersatzzeichenfolge mit $1 in Pythons re.sub einfügen, behandelt Python $1 als die wörtlichen Zeichen Dollar-Eins, und Ihre Ersetzung fügt still $1 in die Ausgabe ein, anstatt des erfassten Werts. Kein Fehler, nur korrupter Text. Das Gegenteil passiert auch: ein \1 in einer JavaScript-Ersetzung wird als Escape gelesen und bricht.
Warnung: Syntaxfehler in Ersatzzeichenfolgen lösen keine Ausnahmen aus. Testen Sie eine Substitution immer an einer echten Beispielzeichenfolge in der Zielsprache, nicht nur am Suchmuster.
Das Dotall-Flag und mehrzeiliges Matching#
Standardmäßig matcht . in beiden Engines keinen Zeilenumbruch. Um das zu ändern, unterscheiden sich die Flag-Namen.
- JavaScript: das
s-Flag (eingeführt in ES2018), wie in/foo.bar/s. - Python:
re.DOTALLoder die Kurzformre.S, übergeben anre.compileoder den Funktionsaufruf.
Das Verhalten nach Aktivierung ist identisch, aber JavaScript hängt Flags als Buchstaben nach dem schließenden Schrägstrich oder als zweites RegExp-Argument an, während Python Flag-Konstanten mit dem bitweisen ODER-Operator kombiniert übergibt, z.B. re.DOTALL | re.IGNORECASE.
Ein portabler Trick: Vermeiden Sie es, sich darauf zu verlassen, dass . Zeilenumbrüche überschreitet. Verwenden Sie stattdessen die explizite Klasse [\s\S] in beiden Sprachen, die jedes Zeichen inklusive Zeilenumbrüche ohne Flag matcht. Dieser eine Trick beseitigt eine der häufigsten sprachübergreifenden Flag-Inkonsistenzen.
Unicode: Eigenschafts-Escapes und Standardverhalten#
Unicode ist der Bereich, in dem die Engines am stillschweigendsten abweichen, und das beißt am härtesten bei nicht-ASCII-Eingaben.
JavaScript behandelt Zeichenketten standardmäßig als UTF-16-Codeeinheiten. Ohne das u-Flag (Unicode) ist ein astrales Zeichen wie ein Emoji zwei Codeeinheiten, und . oder ein Quantifizierer können die Hälfte davon matchen, was zu Mojibake führt. Das Hinzufügen des u-Flags lässt den regulären Ausdruck auf Code-Punkten operieren und schaltet Unicode-Eigenschafts-Escapes wie \p{Letter} und \p{Script=Greek} frei. Das neuere v-Flag erweitert dies um Mengenoperationen.
Python 3-Zeichenketten sind standardmäßig Unicode, daher matchen \w und \d bereits Unicode-Buchstaben und -Ziffern, es sei denn, Sie übergeben re.ASCII. Allerdings unterstützt das eingebaute re-Modul von Python keine \p{...}-Eigenschafts-Escapes. Wenn Sie Eigenschafts-Escapes in Python benötigen, installieren Sie das Drittanbieter-Modul regex, das sie hinzufügt.
| Bedarf | JavaScript | Python re |
|---|---|---|
Match nach Unicode-Eigenschaft \p{L} | u- oder v-Flag | Nicht unterstützt (verwenden Sie regex-Modul) |
| Code-Punkt-korrektes Matchen | Erfordert u-Flag | Standard |
| Nur ASCII-Wortzeichen | Standard ohne u ist teilweise | re.ASCII-Flag |
Die praktische Konsequenz: Setzen Sie in JavaScript das u-Flag, wann immer Ihre Eingabe nicht-ASCII-Text enthalten könnte. In Python erwarten Sie standardmäßig Unicode-bewusste \w/\d, aber greifen Sie nicht zu \p{...}, es sei denn, Sie haben die regex-Bibliothek installiert.
Possessive Quantifiers und Atomare Gruppen#
Dies sind Backtracking-Kontrollfunktionen. Possessive Quantifiers (a++, a*+, a?+) und atomare Gruppen ((?>...)) verhindern, dass die Engine in einen bereits gematchten Teil zurückverfolgt, was katastrophales Backtracking bei böswilligen Eingaben verhindern kann. Das integrierte re von Python hat beide in Python 3.11 hinzugefügt. JavaScripts ECMAScript-Regex unterstützt keines von beiden.
Ein Muster mit (?>...) oder a++ aus einem Python 3.11+ Codebase löst daher in JavaScript einen Syntaxfehler aus. Um eine ähnliche Kontrolle in JavaScript zu erreichen, schreibt man das Muster mit einem Lookahead-plus-Backreference-Trick um (schwerer lesbar) oder strukturiert den Regex so um, dass er von vornherein eindeutig ist.
So testen Sie dasselbe Muster in beiden Varianten#
Der zuverlässigste Weg, all diese Fallstricke zu vermeiden, ist, das genaue Muster vor der Verwendung mit echten Beispieltexten in jeder Variante zu testen. Eine Kompatibilitätstabelle sagt Ihnen, was passieren sollte; das Ausführen des Musters zeigt, was tatsächlich passiert.
Schritt 1: Schreiben Sie das Muster einmal und definieren Sie Ihre Teststrings#
Beginnen Sie mit dem Muster und drei bis fünf Beispieleingaben, die Ihre Grenzfälle abdecken: eine saubere Übereinstimmung, einen Beinahe-Treffer, einen mehrzeiligen Fall und gegebenenfalls einen Nicht-ASCII-Fall. Halten Sie sie vor sich, damit Sie Übereinstimmungen visuell bestätigen können.
Schritt 2: Führen Sie es in der JavaScript-Variante aus#
Fügen Sie das Muster und die Beispiele in einen kostenlosen Multi-Flavor-Regex-Tester ein, der auf die JavaScript-Engine eingestellt ist. Bestätigen Sie die Übereinstimmungen, Erfassungsgruppen und etwaige Ersetzungsausgaben. Achten Sie hier besonders auf das Verhalten von Ankern und die Unicode-Behandlung.
Schritt 3: Wechseln Sie die Variante zu Python und führen Sie es erneut aus#
Ändern Sie die Engine auf Python und führen Sie das identische Muster und die Beispiele erneut aus. Vergleichen Sie die Anzahl der Übereinstimmungen und die erfassten Gruppen mit dem JavaScript-Ergebnis. Ein Unterschied hier ist Ihr Portabilitätsfehler, der erkannt wird, bevor er in die Produktion gelangt.
Schritt 4: Beheben Sie die Abweichung mit den obigen Tabellen#
Wenn die Ergebnisse abweichen, ordnen Sie das Symptom dem entsprechenden Abschnitt zu: Anker, Lookbehind, Syntax benannter Gruppen, Ersetzungsstring oder Unicode-Flags. Wenden Sie die portable Umschreibung an (nummerierte Gruppen, [\s\S] statt dotall, gleich breites Lookbehind) und führen Sie beide erneut aus, bis sie übereinstimmen.
Wenn ein Teil des Musters etwas tut, das Sie nicht entschlüsseln können, kann das Einfügen in einen Code-Erklärer in einfachem Englisch jedes Token aufschlüsseln und die enginespezifischen Teile kennzeichnen, was die Behebung beschleunigt.
Portable Regex schreiben: Eine kurze Checkliste#
Wenn ein Pattern sowohl in JavaScript als auch in Python ohne Verzweigungen laufen soll, halten Sie sich an die gemeinsame Teilmenge:
- Verwenden Sie nummerierte Gruppen und
\1-Rückverweise, keine benannten Gruppen. - Verwenden Sie
[\s\S]anstatt sich auf das Dotall-Flag zu verlassen, um Zeilenumbrüche zu überbrücken. - Halten Sie Lookbehinds auf feste Breite, damit Pythons
resie akzeptiert. - Vermeiden Sie possessive Quantoren und atomare Gruppen.
- Vermeiden Sie
\A/\Zund\p{...}-Property-Escapes. - Testen Sie Ersetzungen separat, da
$1vs.\1ein stiller Fehler ist.
Für Datenaufbereitungsarbeiten, bei denen Sie auch strukturierte Ausgaben neben Ihren Treffern überprüfen müssen, hält die Kombination des Testers mit einem JSON-Formatter die Trefferergebnisse lesbar, während Sie debuggen.
Fazit#
Der Unterschied zwischen JavaScript und Python Regex liegt selten in der sichtbaren Syntax, sondern in den vier stillen Unterschieden, die das Verhalten ändern, ohne einen Fehler zu verursachen: fehlende \A/\Z-Anker, nur Lookbehind mit fester Länge in Python, der $1 versus \1-Ersetzungssplit und die Unterstützung von Unicode-Eigenschafts-Escapes. Merken Sie sich diese vier, verwenden Sie standardmäßig die portable Teilmenge, wenn ein Muster Sprachen übergreift, und testen Sie das genaue Muster in beiden Engines, bevor Sie ihm vertrauen. Diese Gewohnheit verwandelt Regex von einem Copy-Paste-Glücksspiel in etwas, das Sie sicher zwischen Ihrem Frontend und Backend verschieben können.
Häufig gestellte Fragen#
Warum funktioniert mein Regex in Python, aber nicht in JavaScript?
Die häufigsten Ursachen sind Python-spezifische Features in Ihrem Muster: \A/\Z-Anker, Lookbehind mit variabler Länge, possessive Quantoren, atomare Gruppen oder benannte Gruppen (?P<name>...). JavaScripts ECMAScript-Dialekt unterstützt diese nicht, sodass das Muster entweder einen Syntaxfehler wirft oder stillschweigend nichts matcht. Schreiben Sie es mit dem portablen Teil um (nummerierte Gruppen, Lookbehind mit fester Länge, einfaches ^/$) und testen Sie es in beiden Engines.
Unterstützt JavaScript Lookbehind wie Python?
Ja, und in einer Hinsicht ist JavaScript leistungsfähiger. Seit ES2018 unterstützt JavaScript sowohl Lookbehind mit fester als auch mit variabler Länge, während Pythons integriertes re-Modul nur Lookbehind mit fester Länge unterstützt. Ein Lookbehind mit variabler Länge wie (?<=cat|elephant) funktioniert in modernem JavaScript, löst aber in Pythons re einen Fehler aus. Für variables Lookbehind in Python verwenden Sie das Drittanbieter-Modul regex.
Was ist der Unterschied zwischen $1 und \1 bei Regex-Ersetzungen?
Beide referenzieren dieselbe erfasste Gruppe, gehören aber zu unterschiedlichen Engines. JavaScript-Ersetzungsstrings verwenden $1 (und $<name> für benannte Gruppen), während Pythons re.sub \1 (und \g<name>) verwendet. Eine Vermischung führt zu keinem Fehler, sondern fügt die Literalzeichen ein und verfälscht stillschweigend die Ausgabe. Testen Sie Ersetzungen immer mit einem echten Beispielstring in der Zielsprache.
Sind JavaScript- und Python-Regex-Dialekte kompatibel? Sie teilen den Großteil der Syntax, etwa die üblichen 80%, einschließlich Zeichenklassen, Quantoren, Alternativen und nummerierte Rückverweise. Sie unterscheiden sich bei Ankern, Lookbehind-Breite, Syntax benannter Gruppen, Ersetzungsstrings, Inline-Flags, possessiven Quantoren und Unicode-Eigenschafts-Escapes. Ein auf die gemeinsame Teilmenge beschränktes Muster läuft unverändert in beiden; alles Darüberhinausgehende benötigt engine-spezifische Verzweigungen oder eine Umschreibung.
Wie matche ich Unicode-Zeichen nach Eigenschaft in jeder Sprache?
Aktivieren Sie in JavaScript das u- (oder v-)Flag und verwenden Sie Eigenschafts-Escapes wie \p{Letter} oder \p{Script=Greek}. Pythons integriertes re-Modul unterstützt \p{...} überhaupt nicht, daher installieren Sie das Drittanbieter-Modul regex, um Eigenschafts-Escapes zu erhalten. Standardmäßig macht Pythons re in Version 3 \w und \d bereits Unicode-bewusst, während JavaScript das u-Flag für korrekte Codepunkt-Matches benötigt.
Was ist der schnellste Weg, um den Unterschied zwischen zwei Regex-Dialekten zu finden? Führen Sie das exakte Muster und denselben Satz von Beispielstrings durch einen Multi-Dialekt-Regex-Tester, schalten Sie die Engine von JavaScript auf Python um und vergleichen Sie Match-Anzahlen und erfasste Gruppen. Jeder Unterschied in der Ausgabe ist Ihr Portabilitätsfehler, isoliert bevor er ausgeliefert wird. Dies ist schneller und zuverlässiger als das alleinige Studieren von Kompatibilitätstabellen, da es das tatsächliche Verhalten auf Ihren echten Eingaben zeigt.



