NV ToolkitFormat · Validate · Convert

Escape / Unescape

Python Escape / Unescape

Turn any text into a Python string literal body — plain UTF-8, ASCII-only with \u/\U escapes, or a bytes literal — and decode repr() output back.

In short

Escape and unescape Python string literals online: \n, \t, \xNN, \uXXXX and \UXXXXXXXX escapes, ASCII-only and bytes modes, repr() output decoded. Free.

By NaveenKumar T · Updated

  • Escape & unescape in one tool
  • Handles every special character
  • Instant as you switch modes

Runs entirely in your browser — nothing you paste or open here is uploaded, logged, or stored.How we handle data →

Example

Python Escape: input and output

A Windows path, a tab, a quoted word and a line of mixed CJK and emoji — escaped in ASCII-only style, the mode that has to handle every character in the input.

Text
Path: C:\Users\Zoë\notes.txt	"quoted" — 日本語 😀
Python string content (ASCII-only)
Path: C:\\Users\\Zo\xeb\\notes.txt\t\"quoted\" \u2014 \u65e5\u672c\u8a9e \U0001f600

Every backslash doubled and the tab and quote gained their named escapes; ë became \xeb, the em dash \u2014, 日本語 three \uXXXX escapes, and the single emoji one eight-digit \U0001f600 — not a surrogate pair.

Learn more

Python escaping rules

A Python 3 str is a sequence of Unicode code points, and its double-quoted literal form needs backslashes only for the characters that would otherwise end the literal or aren't printable: \" for the quote, \\ for the backslash itself, \n \r \t \a \b \f \v for the named control characters, and \xNN for any other byte below U+0020. Because Python 3 source files are UTF-8, everything else — accented letters, CJK text, emoji — is written as the literal character; there is no requirement to escape non-ASCII the way older C-family literals do. That is the "str" style this tool defaults to, and it is what you want for source code you intend to keep readable.

The "ASCII-only" style instead reproduces what Python's own ascii() and repr() functions do to a string containing non-ASCII: every code point from U+007F upward is escaped, using the narrowest form that fits it — \xNN for U+0080–U+00FF, \uXXXX for the rest of the Basic Multilingual Plane, and \UXXXXXXXX (eight hex digits, one escape per code point) for anything above U+FFFF. That last point is the detail that trips people coming from JavaScript, Java or C#: Python never splits an astral character into a UTF-16 surrogate pair, because Python strings were never UTF-16 to begin with. The "bytes" style is different again — it assumes you are building a b"..." literal, so it UTF-8-encodes every non-ASCII character first and then writes each resulting byte as its own \xNN escape, which is why a single accented letter can expand into two or three escapes.

Python escape sequences

The named escapes below work in every Python string literal regardless of style; \xhh, \uXXXX and \UXXXXXXXX are shown here as this tool emits them, and a raw string (r"...") disables all of them except that a backslash still can't be the last character.

Python string escape sequences
EscapeMeaning
\\Backslash
\' · \"Single or double quote
\n · \r · \tNewline, carriage return, tab
\a · \b · \f · \vBell, backspace, form feed, vertical tab
\0Null character
\oooCharacter named by 1–3 octal digits
\xhhCharacter named by exactly 2 hex digits (U+0000–U+00FF)
\uXXXXCharacter named by exactly 4 hex digits (BMP)
\UXXXXXXXXCharacter named by exactly 8 hex digits (any code point)
\N{NAME}Character by its Unicode name — not decoded here, see the FAQ
\<newline>Line continuation — backslash and the newline are both removed

Python vs JavaScript vs Java string escapes

The four languages agree on the basics — \\, \", \n, \t — and disagree everywhere Unicode is involved, which is exactly where a hand-ported string tends to break.

String-escape differences by language
BehaviorPythonJavaScriptJava
Code point above U+FFFFOne \UXXXXXXXX escapeSurrogate pair: two \uXXXX escapesSurrogate pair: two \uXXXX escapes
\x meaningA code point, U+0000–U+00FF, 2 hex digitsA code point, U+0000–U+00FF, 2 hex digitsNot a recognized escape in a string literal
Octal escapes\ooo (1–3 digits)Not in strict/module modeNot supported
Named Unicode escape\N{NAME}Not supportedNot supported
Unknown escape (e.g. \d)Kept as backslash + character (warns since 3.12)Kept as the character alone in most enginesCompile error

Help

Frequently asked questions

Everything you need to know about the Python Escape.

01How do I escape or unescape Python here?

Choose Escape or Unescape, then a style — str for ordinary Python 3 source, ASCII-only for output that must be pure ASCII (config files, some CI logs), or bytes for a b"..." literal — and press Convert. The output is the literal's body: wrap it yourself in the quote character your code uses.

02Why does Python write é as \xe9 but 😀 as \U0001f600 — no surrogate pairs?

Because Python indexes strings by code point, not by UTF-16 code unit, so there is nothing to pair: 😀 is one code point (U+1F600) and gets exactly one escape, eight hex digits wide, capital U. Compare that with JavaScript or Java, whose strings are UTF-16 internally — a code point above U+FFFF has no single 16-bit slot, so those languages write it as two \u escapes representing a high and low surrogate. \xe9 for é follows a different rule: \x is always exactly two hex digits, so it only covers U+0000–U+00FF, and é (U+00E9) fits inside that range with room to spare.

03What is the difference between the str, ASCII-only and bytes styles?

str assumes your source file is UTF-8 (the Python 3 default) and only escapes the characters a literal actually needs escaped — quotes, backslashes and control characters — leaving accented letters and emoji untouched, so the output stays human-readable. ASCII-only reproduces what repr() shows you in a terminal that can't render Unicode, or what you'd want in a file a strict ASCII-only tool has to parse: everything above U+007E becomes an escape. bytes targets a b"..." literal specifically, where the content is raw bytes rather than text, so a non-ASCII character has to become the UTF-8 bytes that would actually be stored — each one written as its own \xNN.

04How do I unescape a string copied from a traceback or repr()?

Paste it as-is — the tool detects and strips one layer of surrounding quotes, plus an optional b/r prefix, so 'don\'t' and b'hi\\x41' both unescape correctly on their own. repr() of a single-quoted string escapes an embedded single quote as \', which this tool decodes like any other named escape. If your text is meant to be used as a regular-expression pattern afterward, remember that a raw string (r"...") disables backslash processing entirely on the Python side — escape it here only if the string you're building is NOT a raw string.

05Why is \d kept instead of failing?

Because that is what CPython itself does: an escape sequence it doesn't recognize (\d, \q, and similar) is left in the string unchanged — both the backslash and the character survive — rather than raising an error. Since Python 3.6 this has emitted a DeprecationWarning, and 3.12 upgraded it to a SyntaxWarning, but the string still parses. This tool mirrors that behavior exactly and reports how many unrecognized escapes it kept, so you can tell a genuine typo from an intentional regex pattern that was never meant to be unescaped — regex patterns belong in a raw string, or through the [Regex Escape](/regex-escape) tool instead.

Keep working

Related tools