约 8 分钟读完 · 更新于 2026-10-21 · 文中每条都能在下面的配套工具里动手验证
「锟斤拷」「测è¿」「��」这些看着像损坏的字符,其实每一个字节都是对的,只是被按错误的字符集解码了。UTF-8 的中文占 3 个字节,GBK 占 2 个;拿 GBK 的规则去读 UTF-8 的字节,中文就会变成一串拉丁字母和符号。所以排查永远从一件事开始:这个文件当初是用什么编码写出来的,而不是先怀疑文件损坏。
把看到的乱码形态当成指纹去反查,比逐个试编码快得多。中文 Windows 的 Excel 和国产数据库导出常用 GBK/GB18030,而跨平台系统默认 UTF-8,两边撞车就出乱码。
| 你看到的乱码 | 真实编码 | 典型来源 | 修复动作 |
|---|---|---|---|
| 锟斤拷 / 烫烫烫 | UTF-8 被当 GBK 读,又被二次转存 | UTF-8 文本在旧 Windows 记事本里改存 | 按 UTF-8 重新读出,再用 UTF-8 存回去 |
| 飨 这类拉丁串 | UTF-8 被当 Latin-1 / ISO-8859-1 读 | HTTP 响应头没声明 charset,默认按 Latin-1 | 响应头加 charset=utf-8 |
| 测è¿ä¸æ–‡ | UTF-8 被当 GBK 读(最常见) | Linux 导出 CSV 用 Excel 打开 | 导入时手动指定 UTF-8,或导出时加 BOM |
| � 单个替换字符 | 字节序列在当前编码里无对应字符 | 文件被截断,或声明与实际编码不符 | 确认文件完整并核对真实编码 |
| 第一行中文正常,从某行起乱 | 文件内混了两种编码 | 多次追加写入,日志与 CSV 拼接 | 按行定位后整段重新转码 |
| 中文正常但引号变成 “ | UTF-8 被当 GBK 读后再存成 UTF-8 | 经过一层错误的转码工具 | 对全文做一次「误解码 → 重编码」还原 |
原始字节(UTF-8): e4 bd a0 e5 a5 bd → 你好 按 UTF-8 读: 正常 → 你好 按 GBK 读: e4bd=ä½ a0e5=¥ a5bd=½£ → ä½¥½£ 按 GBK 读再存 UTF-8: 多了一层错误转码,之后每次修都在错上加错
① 导出时加 BOM: \xEF\xBB\xBF + 内容 (Excel 双击即正确,脚本读时记得剥掉 BOM) ② 导入时手动指定: 数据 → 从文本/CSV → 原始文件选「65001: Unicode (UTF-8)」,分隔符选逗号
同一个双击动作背后,Excel 至少要猜三件事:文件是什么编码、字段用什么符号分隔、每列按什么类型解析。猜错任何一件都会得到「看起来导入成功但数据是错的」的结果,而 Excel 不会给你提示。所以稳妥的做法是走「数据 → 从文本/CSV」向导,把三件事都显式指定。
CSV 是纯文本,但 Excel 会主动解释内容。以 =、+、-、@ 开头的单元格,导入后会被当成公式而不是字符串,于是「=1+1」显示 2,「=HYPERLINK(...)」变成可点击的链接。更危险的是从 CSV 里读 DDE 命令的构造,在某些客户端上能触发外部程序调用。触发条件很简单:文件来自不可信的来源,且原样双击打开。
| 坑 | 数据长什么样 | 为什么坏 | 正确写法 |
|---|---|---|---|
| 字段里有逗号 | 张伟,销售部,上海 | 被切成三列,后面全部错位 | 整字段用双引号包起来:"张伟,销售部,上海" |
| 字段里有换行 | 第一行 备注:待处理 | 一条记录被拆成两行 | 引号内允许换行,解析器会正确还原 |
| 字段里有双引号 | 他说"好的" | 引号提前闭合,尾部变乱码 | 双引号写成两个:""他说""好的""" |
| 字段前后有空格 | 上海 , 销售部 | 肉眼难辨的去留差异导致 join 失败 | 解析后统一 trim,别依赖原始空格 |
| 行尾符混用 | 部分行 \r\n,部分行 \n | 部分解析器把 \r 当成内容 | 导出时统一为 \n(或统一 \r\n) |
| BOM 混在数据里 | 第一列名变成 \ufeffid | 字段名对不上,SQL 里找不到该列 | 导出加 BOM,脚本读取时用 utf-8-sig |
从 Word、公众号或网页复制来的表格,字段里常混着全角逗号(,)、全角冒号(:)、不间断空格(U+00A0)和零宽字符(U+200B)。全角逗号在 CSV 里不是分隔符,会被原样留在字段内,于是「看起来分隔正确但列数对不上」;不间断空格的字节是 0xC2 0xA0,肉眼与普通空格一模一样,但比较字符串时永远不相等。清洗的做法是先统一全角标点为半角,再把 U+00A0 和 U+200B 显式删除或替换成普通空格。
最快的办法是不用 Excel 猜:把文件内容粘进 乱码修复工具,依次选 UTF-8 和 GBK 试解,能还原出正常中文的那个就是原编码。想让 Excel 双击直接正确,导出时加 UTF-8 BOM;导出给程序读则相反,不要加 BOM。
需要。风险不在「文件会不会自动执行」,而在「人双击打开」这个动作:以 = + - @ 开头的字段会被 Excel 求值,DDE 构造在部分客户端上能拉起外部程序。最省事的防线是在导入向导里把外部数据的列强制设为文本,导出侧则统一给危险前缀加单引号。
九成是文件里的逗号是全角的「,」,它不是 CSV 分隔符,会被原样留在字段里,于是整行挤成一列。用文本统计工具看一下首行的真实字符就能确认。另一个可能是导出用了分号或 Tab,这是欧洲 locale 的 Excel 默认行为。
规则只有三条:含分隔符、换行或双引号的字段,整个用双引号包起来;字段内的双引号写成两个;行与行之间统一用一种行尾符。满足这三条,Excel、Python csv 模块和 SQL 导入都会解析出一致结果。