String literal escape / unescape
Text tools
Loading
Loading tool
The tool is loaded only when you open it.
All processing for this tool happens in your browser. Your input is not sent to a server.
About this tool
Prepare one string for a source-code fixture, or inspect the value represented by an escaped string without running code. Choose JSON, JavaScript or Python, the quote delimiter and whether the input/output is a complete literal or only its escaped contents. Escape always produces ASCII. Unescape uses a deliberately restricted grammar, so it is a representation tool rather than a general language parser. Review the ASCII preview before copying decoded text, especially when it contains line breaks, invisible characters or malformed UTF-16.
Common uses
- Create a JSON string value from text containing quotation marks, backslashes and exact CRLF line endings.
- Prepare a JavaScript or Python test fixture with visible escapes for emoji, separators and bidirectional controls.
- Decode one known literal or its contents to inspect a log value without evaluating an expression or executing imported code.
How to use it
- 1.Choose the language, escape or unescape, and complete-literal or content-only form. JSON uses double quotes; JavaScript and Python allow the selected single or double quote. Escape input is always raw text, even when it looks like an escape.
- 2.Paste text or import one strict UTF-8 file. Complete-literal unescape requires exactly one matching quoted literal with no surrounding expression; content-only unescape omits those outer quotes and still applies the selected delimiter rules. Run the conversion explicitly.
- 3.Review the ASCII preview and UTF-16 counts, then copy or download the complete result. Decoded lone surrogates block raw clipboard and UTF-8 export. Changing input or options invalidates the previous result; a new conversion is required.
Worked examples: exact requests and results
Quotes, slash and backslash
{"input":"say \"hi\" / C:\\tmp","mode":"json","quote":"double","operation":"escape","form":"literal"}{"output":"\"say \\\"hi\\\" / C:\\\\tmp\"","utf8Safe":true}The forward slash stays literal; the quote and backslash are escaped.
Preserve CRLF and controls
{"input":"A\r\n\t\u0000\b\f","mode":"json","quote":"double","operation":"escape","form":"literal"}{"output":"\"A\\r\\n\\t\\u0000\\b\\f\"","utf8Safe":true}CR and LF remain separate; NUL has an explicit four-digit escape.
Use a JavaScript single quote
{"input":"don't","mode":"javascript","quote":"single","operation":"escape","form":"literal"}{"output":"'don\\'t'","utf8Safe":true}Only the chosen single-quote delimiter needs escaping here.
Escape an emoji in JSON
{"input":"\ud83d\ude00","mode":"json","quote":"double","operation":"escape","form":"literal"}{"output":"\"\\ud83d\\ude00\"","utf8Safe":true}One supplementary character uses two UTF-16 surrogate escapes.
Escape an emoji in Python
{"input":"\ud83d\ude00","mode":"python","quote":"double","operation":"escape","form":"literal"}{"output":"\"\\U0001f600\"","utf8Safe":true}The same scalar uses an eight-digit Python Unicode escape.
Expose separators and bidi control
{"input":"\u2028\u2029\u202e","mode":"json","quote":"double","operation":"escape","form":"literal"}{"output":"\"\\u2028\\u2029\\u202e\"","utf8Safe":true}All three invisible characters become visible ASCII spellings.
Omit only the outer quotes
{"input":"line\nend","mode":"json","quote":"double","operation":"escape","form":"content"}{"output":"line\\nend","utf8Safe":true}The escaped newline is retained, but outer quotes are not added.
Decode a JSON escaped slash
{"input":"\"a\\/b\"","mode":"json","quote":"double","operation":"unescape","form":"literal"}{"output":"a/b","utf8Safe":true}The allowed slash escape decodes to an ordinary slash.
Decode JavaScript extensions
{"input":"\"\\x41\\u{1F600}\\v\\0\"","mode":"javascript","quote":"double","operation":"unescape","form":"literal"}{"output":"A\ud83d\ude00\u000b\u0000","utf8Safe":true}Hexadecimal, braced Unicode, vertical tab and isolated zero are accepted.
Decode Python extensions
{"input":"\"\\a\\v\\x41\\U0001F600\"","mode":"python","quote":"double","operation":"unescape","form":"literal"}{"output":"\u0007\u000bA\ud83d\ude00","utf8Safe":true}Bell, vertical tab, hexadecimal and eight-digit Unicode are accepted.
Retain a lone surrogate diagnostically
{"input":"\"\\uD800\"","mode":"json","quote":"double","operation":"unescape","form":"literal"}{"output":"\ud800","utf8Safe":false}The exact UTF-16 unit is retained; raw UTF-8 and clipboard output are blocked.
Reject a JSON hexadecimal escape
{"input":"\"\\x41\"","mode":"json","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}JSON does not support xHH escapes.
Reject a template literal
{"input":"`hello ${name}`","mode":"javascript","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}This tool does not evaluate template interpolation.
Reject a Python raw prefix
{"input":"r\"\\n\"","mode":"python","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}Raw-prefixed strings are outside the tool’s accepted subset.
Reject ambiguous Python surrogates
{"input":"\"\\uD83D\\uDE00\"","mode":"python","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}Use a single eight-digit U escape for this Python scalar.
Reject an unknown escape
{"input":"\"\\q\"","mode":"javascript","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}The restricted decoder rejects unknown escapes instead of guessing.
Reject an octal escape
{"input":"\"\\141\"","mode":"python","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}Octal is excluded even where a language runtime supports it.
Reject an expression
{"input":"\"a\" + \"b\"","mode":"javascript","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}Only one literal is accepted, never a source expression.
Reject triple quotes
{"input":"\"\"\"hello\"\"\"","mode":"python","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}Triple-quoted strings are outside this ordinary-literal subset.
Reject a line continuation
{"input":"\"a\\\nb\"","mode":"javascript","quote":"double","operation":"unescape","form":"literal"}{"rejected":true}A backslash followed by a physical newline is excluded.
Common mistakes and rejected forms
- Selecting JSON for a single-quoted literal or a JavaScript xHH escape.
- Pasting surrounding code, a semicolon or concatenated literals into complete-literal mode.
- Using a Python raw prefix, f-string, bytes prefix or triple-quoted string.
- Expecting an unknown escape, octal spelling or backslash-newline continuation to be accepted.
- Treating content-only output as a complete quoted string without adding the matching delimiter.
- Mistaking a printable ASCII preview for raw decoded text, or treating escaped confidential text as redacted.
Limits and notes
- Input is limited to 65,536 UTF-16 units, output to 524,288 units and a local UTF-8 file to 262,144 bytes. Invalid UTF-8 is rejected, and a leading U+FEFF is preserved. No normalization or newline conversion is requested by the core; browser paste and clipboard behavior can differ. Limits cause errors instead of silently shortened exports. Escaping can expand the result beyond the 65,536-unit input limit, so a large generated literal may not fit back into this tool for decoding. The complete preview is bounded to 393,218 characters; the interface shows at most 8,192 preview characters with a truncation notice, without truncating the stored output.
- The accepted grammar is a subset of each language: no expressions, comments, concatenation, templates, triple quotes, raw/byte/f-string prefixes, named Unicode escapes, octal escapes, unknown escapes or line continuations. A rejection can be a tool restriction even when a runtime accepts the spelling. Raw C0 controls and DEL are rejected during decoding; encode them as escapes. Python also rejects raw unpaired surrogates and every octal form, including backslash-zero. JavaScript braced Unicode escapes accept 1–6 hexadecimal digits.
- JSON accepts its standard quote, backslash, slash, b/f/n/r/t and four-digit Unicode escapes. JavaScript additionally supports xHH, u{...}, v and zero only when no digit follows. Python supports quote/backslash, a/b/f/n/r/t/v, xHH, four-digit u and eight-digit U escapes; escaped slash is not accepted. Do not move a spelling between languages without checking the target grammar.
- Supplementary characters become two four-digit surrogate escapes in JSON/JavaScript and one eight-digit U escape in Python. Python decoding rejects an adjacent escaped high/low surrogate pair rather than silently merging two Python code points into one JavaScript scalar. A lone surrogate can be retained as ASCII escape text; decoded raw output with an unpaired surrogate is not valid UTF-8 and cannot be copied or downloaded.
- The conversion runs locally without uploading inputs or executing them. ASCII previews expose controls, U+2028/U+2029 and bidi characters without rendering them live. Escaping is neither encryption nor redaction and does not automatically make output safe for HTML, a script element, SQL or a shell. Apply the receiving context’s own rules.
Frequently asked questions
What is the difference between a literal and content-only mode?
A complete literal includes its selected outer quotes. Content-only mode omits them, but still escapes and checks the selected delimiter. It is intended for an existing quoted location, not for an unquoted expression. The examples show requests and expected results as ASCII JSON to make every backslash explicit.
Does unescape run JavaScript or Python?
No. It parses only the documented escape subset. It does not use eval, import code or interpret expressions. Backticks, interpolation, prefixes and concatenation are rejected rather than executed.
Why does Python reject two surrogate escapes that JSON accepts?
Python strings treat those escapes as two separate surrogate code points. A JavaScript string could join their UTF-16 units into one supplementary character. This tool rejects that ambiguous Python spelling; use an eight-digit U escape for the intended scalar.
Is a successful conversion safe to paste into HTML or a database query?
Success only means the selected representation was converted. For example, escaping ordinary string quotes does not protect an HTML script-closing sequence. Use a context-aware HTML serializer, parameterized SQL or the appropriate shell mechanism separately.
- RFC 8259 §7–8: JSON strings and interoperability
- ECMAScript: String literals
- Python: String and bytes literals