上个月帮同事整理一份活动说明,他从公众号后台的正文编辑器里全选复制,粘到我这边的文档里。看着是三段话,实际上每句中间夹着 <p> 和 </p>,段落末尾还拖着一串 ,行距被拉得老长。我用编辑器的清除格式功能清了一遍,标签没了,那批空白字符却还留在原地,导出 PDF 时行尾出现难看的参差。
这类事我遇到过不止一次,后来才想明白:问题不在于"复制粘贴"这个动作,而在于同一段内容其实有三种不同的存在形态,粘错了形态就会拿到错的字符。
同一段文字在系统里有三种形态
第一种是渲染结果,也就是浏览器画在屏幕上、你眼睛看到的版本:字号、行距、缩进都是样式算出来的,复制时这些表现层信息不会被带成可读的文字。第二种是 HTML 源码,<strong>、<br>、<img> 这类标记是它的骨架,从"查看网页源代码"里拿到的就是这种。第三种是纯文本,标签全部消失,只剩字符本身。
粘贴的目标软件会自己去挑一份表示来用。挑中源码,标签就变成正文里的普通字符;挑中渲染结果,间距就按对方的样式规则重排。我后来做的判断很简单:粘进去以后先用显示不可打印字符看一眼,就知道自己拿到的是哪一种。
| 形态 | 里面实际有什么 | 粘进 Word 或代码里会怎样 |
|---|---|---|
| 渲染结果 | 看得见的内容与段落间距 | 间距由目标软件的样式决定,和原页面对不上 |
| HTML 源码 | <p>、<br>、<div>、属性、注释 <!-- --> |
标签被当成正文,字数虚高,字符串常量直接截断 |
| 实体写法 | 、"、&、“ |
引号显示成 ",代码里双引号提前闭合 |
| 纯文本 | 只有字符和换行 | 结构信息(层级、列表、强调)全部丢失 |
该留标签的场景,和该去干净的场景
早期我一律去到底,后来发现这么干会把有用的东西一起铲掉。判断依据我总结成一条:下游有没有解析器。
如果这段文字最终要回到网页、邮件模板、富文本编辑器,那 <p>、<ul>、<li> 不是垃圾,是内容结构的一部分。加粗表示强调、列表表示并列、表格表示对照,去掉之后读者只能靠猜。这种情况下我宁可从源码里只删掉指定标签:脚本、样式、注释这些和正文无关的东西清走,剩下的标记原样交回去。
反过来,如果下游只是人或检索,我会去干净。典型有四种:进搜索框做全文查找的正文;要贴回代码里的字符串常量;导成 CSV 或纯文本存档;以及给校对用的字数统计。这四种场景里标签只会制造噪音,尤其是代码里,一个没清理干净的 < 会让整行解析失败。
我自己固定下来的处理顺序
- 先确认拿到的是源码还是渲染结果,粘错形态就别往下做了,重新复制。
- 决定标签的命运:要回网页就只移除指定标签(比如把 script、style、div 单独清掉),只给人读就全部去掉只留文本,注释顺手一并清除。
- 标签去完,剩下的活儿基本是空白字符。我用 HTML标签去除 处理标记,它可以只移除指定标签名(比如 script、style、div),也可以全部去掉只留文本,注释能一并清除;连续空格和换行的压缩我放到下一步,因为那一步对全角空格、制表符、空行的选项更全。
- 实体字符单独处理。别指望去标签这一步会顺手把
解回正常空格,这是两层事情;我看到 & 开头的串就记下来,留到实体解码那一步再动。 - 最后用 文本清理 收边,并拿 字数统计 核对一下处理前后的差值。
第五步不是形式主义。有一回我把整篇稿子压成一行,差值算下来才发现段落分隔符也被吞了:正常清理掉的应该是标签字符数,如果连换行计数一起归零,就说明清理选项开多了。数字对比是唯一能当场发现的办法。
几个我踩过的具体坑
公众号后台的正文里,缩进常常不是真空格而是一串 ,去标签工具不会替你把它变成普通空格,粘进代码里就是一堆无法解释的字符。
另一个坑是嵌套。想删 <div> 时如果只按字符串替换,属性带 class 的开标签会漏掉,闭合标签反而删干净了,剩下的内容看着没问题、粘到别处直接错位。所以我现在更愿意把指定标签的删除交给专门做这件事的工具,而不是手敲替换。
表格内容是最麻烦的一类。表格一旦被压成纯文本,行和列的对应关系就靠肉眼维持,我见过从统计表里复制出来粘进记事本、六列数据糊成两列的例子。这种时候我会保留 HTML,或者干脆把源数据要成 CSV,标签处理再干净也补不回结构。
Q:从网页复制到 Word,标签已经没了,为什么还有空格删不掉?
因为那些不是普通空格。网页里大量使用不换行空格和全角空格,Word 把它们显示为空白但按字符计数,清除格式对它们无效。要按字符类型清,而不是按格式清。
Q:去标签会不会影响文章的字数统计?
会影响"你看到的那份统计",但不该影响正文本身。标签字符本来就不属于内容,去掉之后字数下降是正常的;如果下降幅度接近全文的一半,说明你删的对象里混了正文。
Q:只想删掉脚本和样式,正文标签全留下,可行吗?
可行,这正是指定标签模式的用途。输入标签名即可,比如 script、style、div,其余标记不动,处理完的内容还能直接贴回编辑器。
Q:能不能用查找替换手工删标签?
少量可以,量大就别硬撑。尖括号在正则里有特殊含义,写错一个转义就删多或删少,而删少表现为"看着干净",很难在提交前被发现。
Q:处理 HTML 注释时要注意什么?
注释里经常留着上一版内容和内部备注,它们不影响显示,所以人眼会漏。做正文提取时把注释和标签一起清掉更稳妥。
回到开头那份活动说明:最后的成品既没有标签也没有那串 & 开头的字符,但我是在确认下游只要人读之后才动手全删的。同事后来还要一版贴回后台,那份我是从最初的源码只删指定标签得到的,结构保住了。同一批文字,两个版本,取决于它们要去哪里。