HTML unescape: turn entities back into characters
HTML unescape is the reverse of escaping. It reads character references such as <, é or 🚀 and replaces each one with the character it stands for. Paste text scraped from a web page, an RSS feed, a database column or an API response, and you get the plain text a browser would show.
What the decoder understands
- Named entities. All 2,000+ names in the HTML5 specification, from the everyday
&, and©to→,♥and≂̸. - Decimal references such as
©and hex references such as©or©, including characters outside the Basic Multilingual Plane like emoji. - Legacy forms without a semicolon. Browsers still accept a handful of old entities such as
&or©without the trailing semicolon, and so does this tool, following the HTML5 parsing rules.
Anything that is not a valid reference is left untouched, so a stray & in normal text does not break the output.
Example
Escaped input:
<p>Café &amp; crème © 2024</p>Unescaped output:
<p>Café & crème © 2024</p>Notice that &amp; became &, not &. The input was escaped twice, and a single unescape removes exactly one layer. Paste the result into the Escaped HTML box once more to peel off the second layer.
Spotting double-escaped text
Double escaping is the most common reason people reach for an HTML unescape tool. Typical symptoms are pages that literally show " or &#39;, or product names like “Tom & Jerry” in a feed. It usually means one layer of code escaped the value and a template escaped it again. Unescaping once in this tool tells you what the original text was; the lasting fix is to escape only at output time.
Things to watch out for
becomes a non-breaking space (U+00A0), not a regular space. It looks the same but may not matchin code comparisons or spreadsheets.- Unescaped output can contain real markup again. Never insert decoded text back into a page without escaping it, or you may reintroduce an XSS risk.
- This tool decodes entities; it does not strip tags. To remove markup and keep only the text, use the HTML Stripper.
Need the opposite direction? HTML Escape converts the special characters into entities, and HTML Entities to Text is a focused decoder for symbol-heavy text.
All decoding happens in your browser; nothing you paste is uploaded.
HTML unescape in Python
Python does this in the standard library with html.unescape(), which decodes named entities such as & and © as well as decimal and hexadecimal character references. Older answers that call HTMLParser().unescape() fail with an AttributeError on Python 3.12, where that method no longer exists. The detail people miss most often is double-escaped text: each call removes one level only, so &lt; becomes < first and needs a second call to become <.
import html
escaped = "<p>Tom & Jerry said: "5 > 3" isn't news.</p>"
print(html.unescape(escaped))
# <p>Tom & Jerry said: "5 > 3" isn't news.</p>
# Named, decimal and hex references are all decoded
print(html.unescape("© © © €5")) # © © © €5
# Double-escaped text needs one call per level
twice = "&lt;b&gt;"
print(html.unescape(twice)) # <b>
print(html.unescape(html.unescape(twice))) # <b>
To see what a string should decode to before you write a test for it, paste it above; for the opposite direction use html.escape() or the HTML escape tool.