Die Trennzeichen sind nicht fest, sondern werden in jeder Nachricht selbst deklariert: MSH-1 ist der Feldtrenner (praktisch immer |), MSH-2 die vier Encoding-Zeichen ^~\& (Komponente, Wiederholung, Escape, Subkomponente). Ein Parser, der | hartkodiert, statt MSH-1/2 zu lesen, ist formal falsch — und fällt genau bei dem einen Altsystem auf die Nase, das es anders macht.

Escape-Sequenzen für Trennzeichen im Inhalt:

SequenzZeichen
\F\|
\S\^
\R\~
\T\&
\E\\

Praxisfall: Der Name Müller-Lüdenscheidt & Söhne GbR (Kostenträger!) mit rohem & zerreißt die Komponente in Subkomponenten — ohne Fehlermeldung, die Daten sind einfach falsch verteilt. Umgekehrt zeigt ein \T\ im Anzeigetext, dass die Gegenstelle korrekt escapt. Silent-Failure-Klasse: Die Nachricht bleibt syntaktisch gültig, der Inhalt ist kaputt.

Escape = „dieses Zeichen ist Nutzdaten, nicht Struktur”

Das Grundproblem heißt In-Band-Signalisierung: HL7 v2 benutzt dieselben Bytes für Struktur wie für Inhalt. & trennt Subkomponenten und & steht auch mitten im Straßennamen. Der Parser kann beide nicht unterscheiden, weil sie identisch sind. Escaping ist der vereinbarte Ausweg: man ersetzt das strukturtragende Zeichen durch eine Zeichenfolge, die niemals als Struktur gelesen wird, und der Empfänger dreht das nach dem Parsen zurück.

Der Ablauf ist immer zweistufig und die Reihenfolge ist entscheidend:

Sender:    "Meyer & Sohn-Weg 12"  --escape-->  "Meyer \T\ Sohn-Weg 12"  --> in die Nachricht
Empfänger: Nachricht  --erst nach Delimitern splitten-->  "Meyer \T\ Sohn-Weg 12"
                      --dann unescapen-->  "Meyer & Sohn-Weg 12"

Split zuerst, unescape danach. Wer umgekehrt vorgeht, erzeugt aus \T\ wieder ein echtes & und zerlegt genau daran: der Fehler, den Escaping verhindern sollte.

Die Syntax

Eine Escape-Sequenz ist immer: Escape-Zeichen + Kürzel + Escape-Zeichen. Das Escape-Zeichen ist per MSH-2 als \ deklariert, also \T\, \F\, \S\, \R\, \E\. Das schließende \ ist Pflicht - \T ohne Abschluss ist keine gültige Sequenz.

Neben den fünf Delimiter-Escapes gibt es noch:

  • \X0D\ - beliebiges Byte als Hex (hier <CR>), für Zeichen, die sonst die Nachricht zerlegen würden
  • \.br\ - Zeilenumbruch in formatiertem Text (FT), z. B. in Befundtexten
  • \H\ / \N\ - Highlight an/aus, in der Praxis Kandidat für Müll im Zielsystem, wenn niemand sie entfernt

Die drei Fallstricke, die dir real begegnen

1. Doppeltes Escaping. Ein Kommunikationsserver liest ein Feld aus, schreibt es unverändert in eine neue Nachricht und escaped dabei nochmal. Aus \T\ wird \E\T\E\, weil der Backslash selbst escaped wird. Im Zielsystem steht dann buchstäblich \T\ im Adressfeld. Symptom: Backslashes und Kürzel tauchen sichtbar in der Oberfläche auf.

2. MSH-1 und MSH-2 werden nie escaped. Sie definieren das Escaping erst; ein Parser, der sie durch die normale Unescape-Routine schickt, zerstört genau die Information, die er zum Parsen braucht. Klassischer Bug in selbstgebauten Parsern.

3. Escaping ist nicht überall definiert. Die Sequenzen gehören in Textdatentypen (ST, TX, FT und deren Komponenten). In einem ID- oder IS-Feld hat ein \T\ nichts verloren. Dort ist ein & in den Daten schon das eigentliche Problem, nicht die Kodierung.

Beim Mapping nach FHIR

Hier kippt der Fehler auf die andere Seite: Wenn dein Mapper das Feld nicht unescaped, landet Meyer \T\ Sohn-Weg 12 wörtlich in Patient.address.line[0]. JSON hat keine Ahnung, was \T\ bedeutet — es ist für JSON schlicht ein String, und \ ist in JSON selbst ein Escape-Zeichen, muss also als \\ serialisiert werden. Das Ergebnis validiert sauber gegen jedes ISiK-Profil und ist trotzdem falsch.

Das ist der Kern: Escaping-Fehler produzieren gültige Nachrichten mit falschem Inhalt. Keine Validierung fängt sie, nur ein Abgleich Quelle↔Ziel auf Feldebene.

Merksatz:

Escaping ist die einzige Stelle in HL7 v2, an der Nutzdaten und Struktur sauber getrennt werden — und die Trennung ist rein konventionell, nicht erzwungen. Deshalb hält sich niemand zuverlässig dran.

Siehe auch: Nachrichtenaufbau