String Escape / Unescape

Escape and unescape strings for JSON, JavaScript, Java, C, Python, HTML, XML, CSV, SQL, regex and shell, checked against each language. Errors show where.

  • Runs in your browser
  • Your data never leaves your browser
  • Free · No Sign-Up
Sets whose string rules are used. The options shown change with the format and direction: quote style and non-ASCII handling for JavaScript and Python, \uXXXX output for JSON, non-ASCII handling for Java and C, character references for HTML, attribute values for XML, delimiter, quoting and formula guard for CSV, dialect for SQL. Regular expression and Shell have none, and most options appear for Escape only. Changing the format keeps your text and converts it again. The format, direction and options are remembered on this device; the text is not.
Escape turns plain text into the inside of a string literal in the chosen format. Unescape reads such a literal back into text. Switching keeps what is in the input box and converts it again. Swap moves the result into the input box and then switches the direction.
Off: the output is what JSON.stringify writes, and non-ASCII characters stay as they are. On: every character above U+007E becomes \uXXXX, with a surrogate pair for characters above U+FFFF, which is what Python json.dumps writes by default. \uXXXX writes every non-ASCII character as \uXXXX, with a surrogate pair above U+FFFF. \u{…} writes characters above U+FFFF as one \u{…} escape instead. Keep as is leaves visible characters alone and still escapes invisible ones, such as the zero-width space, the byte order mark and spaces other than U+0020. U+2028 and U+2029 are escaped in every setting. UTF-8 bytes writes each non-ASCII character as its UTF-8 bytes, one three-digit octal escape per byte. \u / \U writes universal character names. Keep as is leaves visible characters alone; invisible ones still become universal character names. In every setting, U+0080 to U+009F are written as bytes, and the second ? of ?? becomes \? so that no trigraph forms. Applies when the value starts with = + - @, their full-width forms, a tab or a line break. Off leaves the value as it is and adds a warning to the status line. ' prefix puts an apostrophe before the value and quotes the field. Tab prefix (Excel) puts a tab before the value inside the quotes; the tab stays in the data. Standard doubles each single quote and leaves the backslash alone; the status line warns when the text contains a backslash or U+0000. MySQL / MariaDB writes the single quote, double quote, backslash, NUL, line feed, carriage return and Ctrl+Z as backslash escapes. Unescape follows the same dialect and takes the value with or without its surrounding single quotes.

The result updates while you type. Example fills in a sample for the current format. For Unescape, paste the literal with or without its quotes: when the whole input is one quoted literal, the quotes are removed and the status line says so. That covers double quotes in JSON, Java and C, single, double and backtick quotes in JavaScript, single and double quotes in Python, and single quotes in SQL. A ¥ or ₩ typed in place of the backslash is not an escape; the status line names the character.
This box is read-only. Copy copies it; Swap moves it into the input box and reverses the direction. When the input is not valid for the format, the box is emptied and the status line names the problem and where it is. Positions and character counts are in Unicode code points, so 😀 counts as one; input with line breaks gets a line and a column instead.
Examples, details and FAQ Worked examples, how it compares with other tools, and answers to common questions.

Example: an Escaped Log Line

Logs that wrap JSON inside a JSON string arrive with every quote escaped. Paste the inner value into JSON → Unescape:

Input:  {\"level\":\"error\",\"msg\":\"disk \\u2192 full\"}
Output: {"level":"error","msg":"disk \u2192 full"}

The output is JSON again, so \u2192 stays escaped: it was written as \\u2192 in the input, one level deeper. Run Unescape a second time on the msg value to get the arrow. This one-level-at-a-time behavior is what JSON.parse does, and the tool checks every input against it.

Example: a Windows Path in Three Formats

The same text needs different escaping depending on where it goes. O'Reilly\Books:

FormatOutputWhy
SQL, StandardO''Reilly\BooksISO SQL only doubles '. PostgreSQL (with the default standard_conforming_strings = on), SQLite, SQL Server and Oracle read \ as a normal character.
SQL, MySQLO\'Reilly\\BooksMySQL treats \ as an escape character unless NO_BACKSLASH_ESCAPES is set (MySQL 8.4 manual, Table 11.1). In Standard mode the tool warns about the backslash.
JSONO'Reilly\\BooksJSON escapes \ and ", not '.

For a shell argument the tool gives the same output as Python’s shlex.quote: it's my file.txt becomes 'it'"'"'s my file.txt'.

How Each Format Is Checked

Each format follows its specification, and scripts/test-string-escape.mjs in the source repository checks the output against the language itself, not against hand-written strings:

FormatRulesChecked against
JSONRFC 8259 §7JSON.stringify / JSON.parse, Python json.dumps
JavaScriptECMA-262 string literals, strict modeevaluation as "", '' and template literals
JavaJLS §3.3 and §3.10.7javac 21
C / C++C11 §6.4.4.4cc -std=c11, with trigraphs on
Pythonlexical analysis, escape sequencesrepr(), ascii(), ast.literal_eval
HTMLWHATWG character referencesthe entities decoder
XMLXML 1.0 §2.2 and §4.6Python ElementTree
CSVRFC 4180 §2Python csv
SQLISO quote doubling; MySQL Table 11.1sqlite3
RegexECMAScript syntax characters plus /RegExp with flags none, u and v; Python re
ShellPOSIX quoting, $'…'shlex.quote, /bin/sh, bash

Three details from these rules are easy to get wrong. A NUL followed by a digit must be written \x00 in JavaScript: \0 followed by 1 is the legacy octal escape \01, a SyntaxError in strict mode. In Java, a line break must be \n, never \u000a, because javac replaces Unicode escapes before it reads the string (JLS §3.10.5). In HTML, an emoji such as 😀 needs one reference, 😀; two references for its UTF-16 halves decode to two replacement characters.

Errors and Notes

The tool does not guess. When the input is not valid for the chosen format, the status line names the problem and where it is:

InputFormatMessage
it\'sJSON\' at position 3: JSON has no \' escape. Write ’ without a backslash.
a\01bJavaScriptlegacy octal escape, SyntaxError in strict mode; write \x01 instead
\x41BCClarger than FF: a \x escape reads every hexadecimal digit that follows
a.bRegex. is a pattern operator, not a literal character
$HOME/notes.txtShell$HOME is expanded by the shell, so the value depends on the environment

Notes do not block the result. CSV warns when a value starts with =, +, -, @, a tab or a line break, which spreadsheet apps can run as a formula (OWASP CSV Injection). The formula guard offers OWASP’s two fixes: a ' prefix inside quotes, or a tab prefix, which OWASP describes as more reliable in Excel. The SQL format always repeats OWASP’s advice that escaping does not reliably prevent SQL injection; use parameterized queries (OWASP SQL Injection Prevention Cheat Sheet).

How It Compares

We ran the same inputs through four tools that rank for “string escape” and “escape string online” on Bing (desktop Chromium, 2026-10-01):

  • escape.utils.com: JavaScript/JSON escape of hello world returns \bhello\b \bworld\b, inserting a backspace escape at every word boundary. Unescape leaves \x4, \u{1F600} and a\qb unchanged without a message.
  • lddgo.net: sends the text to openapi.lddgo.net for every conversion. JSON unescape turns a\qb into aqb and \x4 into x4 silently; \u{1F600} returns a server error.
  • codertools.net: JavaScript escape of NUL followed by 1 gives a\01, the legacy octal form. Invalid escapes pass through unchanged.
  • devlab.itlibra.com: “HTML entities (all non-ASCII)” writes 😀 as ��.

This tool gives \x001, 😀 and positioned errors for the same inputs, and never sends text over the network.

To see which invisible characters a string contains before escaping it, use the Invisible Character Detector. For percent-encoding use URL Encode / Decode, for a full entity table the HTML Entity Encoder, and to try an escaped pattern the Regex Tester.

Limits

  • The input is one string value. CSV unescape reads one field, not a whole file; Shell unescape reads one argument and stops at unquoted whitespace.
  • Python \N{NAME} escapes are reported, not decoded: the Unicode name table is not included.
  • HTML escape covers text and quoted attribute values. JavaScript inside <script>, CSS and URLs need their own encoding.
  • Regex escape is for use outside character classes. Python’s verbose mode (re.X) also treats spaces and # as syntax.
  • Characters that XML 1.0 forbids (most C0 controls, U+FFFE, U+FFFF, unpaired surrogates) cannot be escaped and are reported.
  • Shell $'…' follows bash, including \u and \U; POSIX.1-2024 defines the form without them.
  • About 360,000 characters convert in well under a second; much larger inputs work but make the text boxes slow to redraw.

FAQ

Why does JSON unescape say a quote would end the string?

Unescape expects the inside of a string literal, where every double quote is written as \". If you paste JSON that is already unescaped, such as {"a":1}, the first quote is reported because there is nothing left to unescape. If the whole input is one quoted literal, such as "a\nb", the tool removes the outer quotes for you and says so.

What is the difference between the JavaScript and JSON formats?

JSON (RFC 8259) has only \" \\ \/ \b \f \n \r \t and \uXXXX. JavaScript also has \' \v \0 \xHH, \u{…} and line continuations, and it turns an unknown escape such as \d into the letter itself. The tool escapes JSON exactly like JSON.stringify and reports \' or \x in JSON input as errors.

Is the SQL format safe against SQL injection?

No. Doubling single quotes produces a valid string literal, but OWASP lists escaping as strongly discouraged because it depends on the database, its settings and the character set. Use parameterized queries in application code. The SQL format is for writing one-off scripts, fixtures and migration files by hand.

Why is my ¥n or ₩n not turned into a line break?

Japanese and Korean Windows fonts draw the backslash (U+005C) as ¥ or ₩. If you retype an escape from such a screen, you may type the real yen sign U+00A5 or won sign U+20A9, which is not an escape character. The tool keeps the text and adds a note naming the character.

Is my text sent to a server?

No. All 11 formats run in your browser. HTML references are decoded by the browser's own parser in a document that cannot run scripts or load images. Only the selected format, direction and options are remembered on this device.