使用方法
- 把 HTML 源码粘进「输入 HTML」,默认示例是一段含加粗、列表、链接、 与 & 的完整片段,打开页面就能直接转换。
- 三个选项控制还原口径:链接是否保留网址、列表是否加圆点、U+00A0 是否归一为普通空格,全部默认开启。
- 点「转换为纯文本」,或在输入框里按 Ctrl+Enter(Mac 是 Cmd+Enter)。Enter 键保留给换行,不会误触发转换。
- 结果区上方是统计条:输出字符数、行数,以及同一份输入按 textContent 口径会得到多少字符,方便核对换行还原了多少。
- 实体对照表默认 12 行,点「加载更多」补齐 17 行;「导出 CSV」带 BOM 头,Excel 打开中文不乱码。
这个HTML转纯文本转换器能解决什么
从网页或富文本编辑器里复制出来的内容带着一堆标签:本页把它还原成段落分明、列表成行的纯文本,直接可贴进邮件、文档或不支持 HTML 的后台。
链接不能丢:默认把 <a href="...">示例站点</a> 还原成「示例站点 <网址>」,网址里的 & 也会被解码成 &,纯文本读者仍然知道链接指向哪里。
字符统计对不上号:很多页面用 排版,它的码位是 U+00A0 而不是空格的 U+0020,按字符统计时会多出隐形字符。本页默认把它们归一,也可以关掉保留原样。
要保住段落结构:块级元素之间补换行、列表项加圆点,转出来的文本保持可读的行列关系,而不是挤成一整行。
本页做的是「还原成可读文本」,不做语法转换、源码排版或合法性检查:转 Markdown 属于 HTML转Markdown转换器,缩进排版属于 HTML格式化,标签合法性属于 HTML校验,压缩源码属于 HTML压缩,见下方相关工具。
原理与规则说明
HTML转纯文本转换器先用 new DOMParser().parseFromString(html, 'text/html') 解析,再对 body 做深度优先遍历:文本节点(nodeType 3)原样输出,元素节点(nodeType 1)按标签分派。实体解码由解析器按 WHATWG HTML 标准的命名实体表自动完成,不需要本页再做一层替换。
为什么不用 textContent 一步取值:textContent 把所有文本节点直接拼接,块级元素之间不会补换行。演示输入按这个口径只有 57 个字符、1 行,而本页口径是 98 个字符、6 行,差的 41 个字符就是补上的换行、空行和列表圆点。它还有个坑:script 与 style 的内容也会被算进 textContent。
为什么不用 innerText:innerText 的结果取决于渲染布局(表格会插制表符、隐藏元素被剔除),而 DOMParser 解析出的文档没有进入渲染树,行为不可靠且规范留白。「所见即所得」的取值应该在真实渲染的 DOM 上做,解析场景的正确工具是 textContent 加自己的块级处理。
块级换行怎么补:内置 P、DIV、H1~H6、UL、OL、LI、TABLE、TR、BLOCKQUOTE、PRE、HR 等块级标签集合,进入和离开时各补一个换行;BR 直接给一个换行;LI 在进入时补圆点 U+2022。行内标签 strong、em、span 不产生任何换行,只保留文字。
链接与空白:A 标签先递归取文字,再按选项追加 <href>;之后统一做空白归一——连续空格折叠成一个、行首行尾空白删掉、U+00A0 按选项替换成 U+0020。注意 160 和 32 是两个不同码位,正则 \s 默认不把 U+00A0 当空白,所以必须显式替换。
环境兜底:没有 DOMParser 的个别内嵌 WebView 里退回字符级 tokenizer——注释整段跳过、引号内的 > 不算标签结束、script 与 style 内容丢弃、内置 17 个命名实体加数字实体 &#NN; 与 &#xHH; 的解码,两条路径对常见实体的输出一致。
完整示例(数值仅作演示)
默认输入是一段 198 字符(UTF-8 290 字节)的 HTML,含 4 个实体引用( × 3、& × 1)、6 个块级开始标签、1 个 BR、2 个 LI、1 个带 href 的 A。
默认选项输出 98 个字符、6 行:第一行来自 P,第二三行来自两个 LI(各带圆点),第四行来自链接段落(网址以尖括号跟在文字后,& 已解码),BR 单独成行,再空一行之后是最后一个 P。关掉「列表加圆点」则圆点消失、行数不变;关掉「链接保留」则只剩「示例站点」四个字。
关掉「U+00A0 归一」后,输出里会残留 3 个 U+00A0(码位 160);开着的输出里它们全变成普通空格(码位 32)。这一格差异正是字符统计口径差一截的原因。
给一段属性里带大于号的输入 <a title="1 > 0">链接</a>:引号内的 > 不会让解析提前结束,输出是「链接」。若用正则剥标签,会从第一个 > 处截断,留下 0">链接 这样的残渣。
输入范围与对照表
| 输入规模 | 本页行为 | 说明 |
|---|---|---|
| 0 字符 | 拒绝 | 提示输入为空 |
| ≤ 204800 字节 | 正常转换 | 常规文章与邮件源码的量级 |
| 204800 ~ 512000 字节 | 转换并提示 | 统计条标注体积,建议拆段 |
| > 512000 字节 | 拒绝 | 避免长解析卡住标签页 |
| DOM 节点 > 50000 | 转换并提示 | 深页面的节点规模告警 |
实体对照见工具区的 17 行表格:命名实体(&、 等)与数字实体('、©)都在处理范围;未收录的命名实体会原样保留在输出里,不会变成空字符串。
常见误用对照:把本页当「标签删除器」用。删标签字符和还原文本是两件事——a < b 且 c > d 这种数学式文本用正则剥标签会变成「a d」,本页不把它误判为标签,输出原样保留。
输入范围、边界与精度说明
体积阈值实测:演示输入 290 字节,远低于 204800 字节的提示线;超过 512000 字节直接拒绝,因为一次整页解析加遍历会把主线程占住数秒。两个阈值之间的输入会正常转换,只在统计条给出体积提示。
未闭合标签由解析器修复:<p><b>未闭合 会被补全成完整结构,输出「未闭合」;只会丢弃 script、style、template、noscript 四类标签的内容,其余标签一律保留文字。
纯文本输入原样返回:没有标签的字符串走完整个流程后只经历空白归一,「没有标签的一段话。」输出不变。连续多个空行会折叠成一个空行,行数统计据此计算。
script 内容必须丢弃:正则剥标签会把 <script>var x = 5 < 6;</script> 漏出「var x = 5」,本页按标签结构整段跳过,输出不含任何脚本文字。
实体解码有两层来源:DOMParser 路径由解析器按标准表解码,覆盖全部命名实体与数字实体;tokenizer 兜底路径只内置 17 个常用命名实体加数字实体,未识别的写法原样保留。所以同一段非常规实体在两条路径下可能不同,这是兜底路径的已知边界。
常见误用的正确解释:转换后字符数比原来多不是 bug——多出来的字符是补上的换行、空行和列表圆点(演示里是 41 个),少掉的部分是被丢弃的标签与 script 内容。统计条同时给出两种口径,可以对账。
常见问题
为什么转换结果和 textContent 不一样?
textContent 直接拼接所有文本节点,不会在块级元素之间补换行,还会把 script 的内容算进去。本页在其基础上补了块级换行、列表圆点和链接网址,统计条同时给出两种口径的字符数。
和普通空格有什么区别?
码位不同:U+00A0(160)对 U+0020(32),正则 \s 不把 U+00A0 当空白,字符统计时它也算一个字符。默认归一成普通空格,关掉选项可保留原样。
链接的网址会保留吗?
默认保留,形式是「文字 <网址>」,网址取自 href 属性并做实体解码。不想要网址就取消勾选「链接还原」。
图片会怎么处理?
img 没有文字内容,也不属于块级换行集合,输出里不会留下痕迹;需要 alt 文本请先用编辑器把它写成正文再转。
表格会变成什么样?
TABLE、TR 属于块级集合,各自产生换行,单元格文字按顺序拼接;这不是结构化导出,需要保留表格结构请用专门的处理。
转换会不会执行页面里的脚本?
不会。DOMParser 只解析不执行,本页还会把 script、style、template 的内容整段丢弃,输出里不会出现脚本文字。
为什么超过 512KB 就拒绝?
解析加遍历都在主线程上做,超大输入会卡住标签页数秒。204800 到 512000 字节之间可以转,但统计条会提示体积,建议拆段处理。
输入的内容会被上传吗?
不会。解析用浏览器原生 DOMParser,遍历与空白归一都是本页内联代码,没有任何网络请求;可以在开发者工具的 Network 面板确认,页面加载后不会再发请求。
相关工具
HTML转纯文本转换器只做「还原成可读文本」这一件事,HTML 相关的其它处理各有专门页面。