文本处理 本地计算 开箱即用 内置示例 不留痕迹

HTML 实体编解码

两种编码档位:仅转义 & < > " ' 五个必要字符防止标签注入,或把中文与 emoji 一并转成 &#x…; 数字实体彻底避免乱码;解码方向把网页源码里的命名与数字实体还原成原文,不认识的实体原样保留。

HTML 里有五个字符有特殊含义:& 是实体的起点、< 是标签的起点、> 收尾、引号包属性。正文里出现它们必须转义,否则轻则排版错乱,重则被注入 <script> 造成 XSS。本工具的「仅必要字符」档做最小安全转义:只动这五个字符,中文原样保留,适合评论、表单内容入库前处理。

「全部非 ASCII」档更进一步:中文、符号、emoji 全部转成 &#x4F60; 这样的数字实体,粘贴到任何编码环境(老系统、邮件、JSON)都不会乱码,代价是体积变大。emoji 按码点整体转换(😀 是 &#x1F600;),不会拆成半个代理对。解码方向则把命名实体(&amp;)与十进制/十六进制数字实体还原成原文,遇到不认识的实体名原样保留不丢内容。

使用步骤

  1. 选处理方向:编码(仅必要字符)、编码(全部非 ASCII)或解码。
  2. 粘贴内容到输入框,结果实时更新。
  3. 编码看转义处数,解码看还原处数,两者都能直接复制结果。
  4. 粘贴回 HTML 源码或目标环境即可。

计算原理与示例

五个必要字符的最小转义

编码的「仅必要字符」档只处理五个有特殊含义的字符:& → &amp;、< → &lt;、> → &gt;、" → &quot;、' → &apos;。这是文本上下文的最小安全集——正文、评论、表单值入库或回显前过一遍,标签注入的入口就被堵住了,中文与其他字符原样保留,体积几乎不变。

数字实体与编码免疫

「全部非 ASCII」档把五个必要字符之外的所有非 ASCII 字符转成十六进制数字实体:中文「你」是 &#x4F60;,emoji「😀」是 &#x1F600;,商标符号 ™ 优先用具名实体 &trade;。数字实体只含 ASCII 字符,放进任何编码环境(老接口、纯 ASCII 通道、邮件)都不会乱码;代价是长度膨胀——一个汉字从 3 字节变成 8 个字符。

解码规则与往返一致

解码方向按 HTML 标准还原:具名实体查表(&amp; → &、&copy; → ©),数字实体支持十进制(&#20320;)与十六进制(&#x4F60;)两种写法,增补平面的高位码点按码点整体还原、不拆代理对。遇到不认识的实体名原样保留——宁可少转换也不丢内容,这对「编码 → 解码」的往返一致性同样成立。

代码示例

JavaScript 用 DOM 做真正的权威编解码

// 浏览器内置的实体表最全:交给 textarea / textContent,别自己维护映射表
const encode = (s) => {
  const el = document.createElement('div');
  el.textContent = s;                  // 先按纯文本放进去
  return el.innerHTML;                 // 取出来时浏览器会按需转义 < > & 等
};
encode('<a href="x">中文</a> & more');  // '&lt;a href="x"&gt;中文&lt;/a&gt; &amp; more'

// 反向:把实体串当 HTML 塞进去,取 textContent 得到原文
const decode = (s) => {
  const el = document.createElement('textarea');
  el.innerHTML = s;
  return el.value;
};
decode('&lt;b&gt;&#x4E2D;&yen;');        // '<b>中¥'

// innerHTML 会解码「全部」实体(含 &nbsp; 等命名实体)——这就是浏览器比手写正则可靠的原因

Python html.escape / html.unescape

import html

html.escape('<a href="x">中</a> & more')
# '&lt;a href=&quot;x&quot;&gt;中&lt;/a&gt; &amp; more'
html.escape('"单引号\'与双引号"', quote=True)     # 默认连引号一起转义

html.unescape('&lt;b&gt;&#x4E2D;&yen;&nbsp;')
# '<b>中¥\xa0'

# 只想转义 < > &(不动引号)时:html.escape(s, quote=False)

常见问题

为什么 < 和 & 必须转义?

< 会被浏览器当成标签的开始,后面的内容可能被解析成元素甚至脚本;& 是实体的起始字符,不转义会和 &amp; 这类真实体混淆。正文内容入库或回显前转义这五个字符是最基础的防注入手段。

「仅必要字符」和「全部非 ASCII」怎么选?

网页正文、数据库存储用前者:只转义五个必要字符,中文可读且体积小。要把文本放进不确定编码的环境(老接口、邮件头、纯 ASCII 通道)用后者:中文 emoji 全转数字实体,绝不会乱码,但长度会翻几倍。

空格为什么不转成 &nbsp;?

&nbsp; 解码后是不换行空格(U+00A0),不是普通空格(U+0020)——转了会改变原文语义,编码再解码就对不回去了。工具保持空格原样,保证编码→解码往返一致。

emoji 转实体会被拆坏吗?

不会。emoji 属于增补平面字符,工具按完整码点转换:😀 转成 &#x1F600; 而不是两个孤立的代理对,解码后原样还原。

不认识的实体会被删掉吗?

不会。解码时遇到不认识的实体名(比如 &nope;)会原样保留,其余部分正常解码——宁可少处理,不丢内容。

编码后体积会变大多少?

「仅必要字符」档几乎不变(只转义出现的 & < > 引号);「全部非 ASCII」档下一个汉字约从 3 字节变成 8 字符(&#x4F60;),emoji 是 10 字符。按目标环境的编码可靠性权衡选择。

能处理整段 HTML 源码吗?

可以。把源码粘进输入框:选「解码」把 &lt;div&gt; 之类的实体还原成可读文本;选「编码」把整段转义成安全的展示文本,标签会以 &lt;div&gt; 形式可见而不是被浏览器执行。

延伸阅读

来自本站原创文章,讲清这个工具背后的算法与口径。