首页/开发/正则与编码速查/BOM 引发的乱码与解析错误

BOM 引发的乱码与解析错误

BOM 造成的故障有两类:被当成正文内容(首行多出不可见字符,比较与解析失败),以及被错误编码解释成可见乱码(UTF-8 的 EF BB BF 按 GBK 显示为「锘」、按 Latin-1 显示为「」)。

正则与编码速查开发更新于 2026-10-17
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌​‌​‌‌​​​‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​​‌‌​‌‌​​‌​‌​‌‌‌​​‌‌​​‌​‌‌​‌​‌‌​​‌‌‌​‌‌​​​​‌​‌‌‌​​‌​​‌‌​​​‌​​‌‌​‌‌​​​‌‌​​‌​‌​‌‌​​‌​​​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

BOM 引发的两类故障

第一类是「看不见的污染」:BOM 被当作字符串的第一个字符读入,首行比较、正则首锚定、JSON 解析、CSV 表头匹配都会莫名其妙失败,日志里却看不出任何异常字符。第二类是「看得见的乱码」:带 BOM 的 UTF-8 文件被按单字节或 GBK 编码解释时,EF BB BF 会显示成可见字符,典型表现是内容以「锘」开头或出现  这样的怪串。判断方法很简单:看文件前三字节是否为 EF BB BF。

基本信息

故障类型一BOM 被当正文:不可见字符污染首行
故障类型二BOM 被当作其他编码解析:显示为锘或 
判定方法读取文件前三字节,比对 EF BB BF
高发文件类型Windows 记事本保存的 txt/csv/ini/bat,编辑器默认带 BOM 的源文件
交付约定需要被解析的文本统一按无 BOM 交付,最省排查成本
修复成本低:剥离文件头三字节即可,但要先备份

典型使用场景

  • shell/批处理脚本无法执行:报错信息指向不存在的命令,实际是 shebang 前有 BOM
  • CSV 导入失败:表头第一列名带不可见字符,按列名取值全部落空
  • JSON/XML 解析报错:内容看起来完全正常,首字符却是一个零宽字符
  • 字符串比较与去重异常:两个看起来一模一样的值被判定为不同
  • 配置项不生效:ini/yaml 的首个键名被 BOM 污染,匹配不上程序里的键

定位与修复示例

定位与修复示例
head -c 3 bad.txt | xxd                     # 先确认前三字节是不是 efbbbf
python -c "print(repr(open('bad.txt', encoding='utf-8').read()[:5]))"   # 首字符会显示为 '\ufeff'
grep -l $'^\xef\xbb\xbf' *.csv                # 批量找出目录里带 BOM 的 CSV
sed -i '1s/^\xEF\xBB\xBF//' bad.csv          # 只剥离开头;执行前务必备份
python -c "s=open('bad.csv', encoding='utf-8-sig').read(); print(s.splitlines()[0])"  # 读时自动忽略 BOM
# 校验:修复后再次确认首三字节与首行内容
head -c 3 bad.csv | xxd

现象与成因对照

现象真实原因处理方式
文件开头显示「锘」UTF-8 BOM 被按 GBK 解码按 UTF-8 读取,或剥离 BOM 后统一为无 BOM
开头出现 UTF-8 BOM 被按 Latin-1 解码确认读取编码,避免二次转码
CSV 首列名匹配不上列名首字符是零宽字符入数据前剥离 BOM
首行字符串比较为假字符串首个字符是 U+FEFF读入时用感知 BOM 的方式打开
脚本报找不到命令shebang 前有 BOM保存为 UTF-8 无 BOM
排查顺序建议:先看字节(hex 前三字节),再看读取编码,最后才看业务逻辑。绕过字节层直接调试业务代码,往往会在日志里看到「一模一样的两个字符串」比较失败,浪费时间。
批量剥离 BOM 属于危险的批量修改操作:脚本写错正则会误删正文内容,或在 UTF-8 文件被按单字节处理后破坏多字节序列。正确做法是先备份、只处理文件首、处理后抽样验证,并在版本库中审查 diff。
根治手段在源头:编辑器与构建工具统一设置「UTF-8 无 BOM」,代码仓库加 .gitattributes 固定文本文件处理方式,CI 里加一条检查首字节的规则,避免同一个问题反复出现。

易错点

  • 只在业务层做 trim:去空白不会去掉 U+FEFF,首行问题依然存在 → 在读取阶段处理 BOM
  • 把带 BOM 的文件按普通 UTF-8 写入数据库:字段值多出一个零宽字符,等值查询与唯一约束都可能失效 → 入库前统一剥离
  • 用全局替换清掉所有 BOM 字节:正文中合法的零宽字符被误删 → 限定在文件首部处理
  • 修复后未回归验证:BOM 没了但内容在转换中被改坏 → 处理后比对关键行与字节总数
  • 把 BOM 乱码当编码整体错误:实际只有开头三个字节有问题,却把整个文件按另一种编码重解,越修越乱 → 先用字节定位,再决定处理范围

数据来源与参考

  • Unicode 官方:U+FEFF 与 BOM 的语义说明
  • RFC 8259:JSON 解析器对 BOM 的处理要求
  • Microsoft 文档:UTF-8 BOM 与文本文件编码选项

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/regex/bom-causes-garbled.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌​‌​‌‌​​​‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​​‌‌​‌‌​​‌​‌​‌‌‌​​‌‌​​‌​‌‌​‌​‌‌​​‌‌‌​‌‌​​​​‌​‌‌‌​​‌​​‌‌​​​‌​​‌‌​‌‌​​​‌‌​​‌​‌​‌‌​​‌​​​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​