HL7 v2 messages are plain text held together by a handful of special characters. If a value needs to contain one of those characters, for example a company name with an ampersand or a note with a line break, the sender has to escape it. Get it wrong and the receiver splits the value in the wrong place, often without any error.
The special characters
The separators are declared at the start of every message, in MSH-1 and MSH-2. Almost everyone uses the defaults:
| Character | Role | Declared in |
|---|---|---|
| | Field separator | MSH-1 |
^ | Component separator | 1st character of MSH-2 |
~ | Repetition separator | 2nd character of MSH-2 |
\ | Escape character | 3rd character of MSH-2 |
& | Subcomponent separator | 4th character of MSH-2 |
Segments end with a carriage return (hex 0D), so a raw line break inside a value ends the segment early.
The escape sequences
An escape sequence starts and ends with the escape character, usually \. These are the ones you'll meet:
| Sequence | Means |
|---|---|
\F\ | A literal field separator (|) |
\S\ | A literal component separator (^) |
\T\ | A literal subcomponent separator (&) |
\R\ | A literal repetition separator (~) |
\E\ | A literal escape character (\) |
\Xhh…\ | Hexadecimal data, for example \X0D\ for a carriage return or \X0D0A\ for a Windows line break |
\H\ and \N\ | Start highlighting, and return to normal text |
\Zhh…\ | A locally defined escape sequence: its meaning is agreed between sender and receiver |
\C…\ and \M…\ | Switch character set (single-byte and multi-byte) |
Formatting commands
Fields with the FT (formatted text) data type, such as report text, can also carry formatting commands that start with a dot:
| Command | Means |
|---|---|
\.br\ | Line break |
\.sp n\ | Skip n lines (a blank line if n is omitted) |
\.in n\ and \.ti n\ | Indent, and temporary indent |
\.fi\ and \.nf\ | Turn word wrap on, and off |
\.sk n\ | Skip n spaces |
\.ce\ | Center the next line |
Many systems also send \.br\ in plain text fields that aren't FT, so receivers usually need to handle it everywhere.
Examples
A guarantor employer name (GT1-16) such as "Smith & Jones" must be sent with the ampersand escaped:
GT1|1||DOE^JANE|||||||||||||Smith \T\ Jones
A two-line note in an NTE segment, sent as a single segment:
NTE|1||Patient prefers morning appointments.\.br\Interpreter needed: Spanish.
The same line break sent as hexadecimal data:
NTE|1||Patient prefers morning appointments.\X0D0A\Interpreter needed: Spanish.
Common mistakes
- Unescaped ampersands.
Smith & Jonessent as-is becomes two subcomponents, "Smith " and " Jones". Many receivers keep only the first, so the name is silently truncated. - Unescaped carets in free text. A note such as
BP 120^80splits into components. - File paths and backslashes. A Windows path such as
C:\temp\fileis read as escape sequences. Backslashes in data must be sent as\E\. - Raw line breaks. A carriage return pasted into a comment ends the segment, and the rest of the text arrives as a broken "segment" the receiver can't parse.
- Double escaping. An engine that escapes values that were already escaped turns
\T\into\E\T\E\, and the receiver shows the escape sequence instead of the character. - Escaping MSH-1 and MSH-2. The separators themselves are never escaped:
MSH|^~\&|is read literally.
Seeing escapes in context
When you paste a message into PipeHat, the decoded view shows each value with its escape sequences resolved, so Smith \T\ Jones reads as "Smith & Jones" and \X0D0A\ becomes a line break. The raw pane next to it still shows exactly what was sent, so you can compare the two and spot a sender that isn't escaping, or is escaping twice.