HTML Entity Decoder
Convert HTML entities back into the characters they represent.
HTML Entity Decoder tool
What each reference resolved to
| Reference | Character | Code point | Kind |
|---|
Escaping rather than unescaping? Use the HTML Entity Encoder.
What this tool does
It resolves entity references back to the characters they stand for:
é to é, — to an em dash,
😀 to an emoji. Named references, decimal references and hexadecimal
references are all handled, and each one is listed underneath so you can see what resolved to
what.
Text scraped from a page, pulled from an RSS feed or copied out of a database column is full of these. Reading it is unpleasant; searching it is impossible until they are gone.
Common uses
-
Cleaning up scraped content before indexing it —
and’otherwise break every keyword match. -
Fixing a double-escaped field, where a page is showing a literal
&instead of an ampersand. - Reading a CMS export or a WordPress database dump, where smart quotes arrive as numeric references.
- Working out which invisible character a
​in your content is. - Turning an email subject line full of entities back into something legible.
A short example
This input:
Café — “best in town” (½ price) decodes to:
Café — “best in town” (½ price)
Note the space between ” and (: that is a no-break space, U+00A0,
not an ordinary one. It looks identical and will not match a plain space in a search.
Two quirks worth knowing about
Numeric references in the 128–159 range are not what they say. Those code
points are C1 control characters, but authors writing them meant Windows-1252, so the HTML
standard mandates a substitution table. “ is formally a control
character and every browser renders it as a left double quotation mark. This decoder applies
the same table, so you get the character a browser would show.
A missing semicolon is often still decoded. Browsers accept
& without one for a fixed legacy list, which is why
?x=1©=2 can mysteriously become ?x=1©=2. Strict mode turns
that behaviour off if you want to see exactly what a well-formed parser would do.
Worth knowing
Decoded text is not safe text. If the result contains <script>, it now
contains a working script tag — re-escape it before putting it anywhere near a page. The
common shortcut of decoding by assigning to a div's innerHTML and
reading back textContent is exactly how that goes wrong; this tool parses the
references itself and never touches innerHTML.
Frequently asked questions
Why does my text show ’ instead of an apostrophe?
That is a byte-level mix-up rather than an entity problem, so decoding will not touch it: the UTF-8 sequence E2 80 99 for a right single quote has been read as Windows-1252, which spells it out as three characters. Repair the pipeline that produced it — the connection charset, the Content-Type header, or a column still declared latin1 — since find-and-replace only patches the sequences you have already noticed.
The decoded text still does not match my search. What is left in it?
Almost certainly an invisible character that an entity resolved to. A non-breaking space becomes U+00A0 rather than an ordinary space, ­ becomes a soft hyphen that renders as nothing at all, and ‍ and ​ are zero-width. None of them are removed by trim(). Paste the result into the Unicode converter to see exactly which code points survived.
An emoji decoded here but my database rejects it. Why?
MySQL’s utf8 is really utf8mb3: three bytes per character at most, which cannot hold anything above U+FFFF. A decoded 😀 needs four, so the insert fails with error 1366, Incorrect string value, or the column is truncated at that point. Converting the column, the table and the connection to utf8mb4 is the only thing that lifts the limit.