首页/开发/正则与编码速查/字节序标记 BOM 的含义与取舍

字节序标记 BOM 的含义与取舍

BOM 是写在字节流最开头的 U+FEFF,用来声明字节序(UTF-16/32)或弱标识 UTF-8;UTF-8 的 BOM 是 EF BB BF,规范建议不写,HTTP 头、JSON、shell 脚本等场景明确不应出现。

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

BOM 是什么

BOM(Byte Order Mark)本质是字符 U+FEFF(ZERO WIDTH NO-BREAK SPACE)被放在字节流的最前端:解码器先读它,就能推断接下来是多字节单位的哪一种字节序。UTF-16 下小端写作 FF FE、大端写作 FE FF;UTF-32 下是 FF FE 00 00 或 00 00 FE FF;UTF-8 没有字节序问题,它的 EF BB BF 只是一个「我是 UTF-8」的弱信号。也正因为没有必要性,规范对 UTF-8 BOM 的态度是:允许出现但不应主动添加。

基本信息

对应字符U+FEFF(零宽不换行空格)
UTF-8 BOMEF BB BF(3 字节)
UTF-16 小端 / 大端FF FE / FE FF
UTF-32 小端 / 大端FF FE 00 00 / 00 00 FE FF
主要作用声明字节序(UTF-16/32);标识编码(UTF-8,可选)
位置约束只能在流的最开头出现一次

典型使用场景

  • 识别 Windows 生成的文件:记事本另存为 UTF-8 的历史版本会带 BOM
  • CSV 交付给 Excel:带 BOM 的 UTF-8 能让简体中文 Office 正确识别编码
  • 脚本与配置排查:shebang 前多出的 BOM 会让解释器报找不到文件
  • 数据清洗:批量检测并剥离文件头的 BOM,保证下游按 UTF-8 正确解析
  • 编码判定:开头是 EF BB BF 基本可断定文件为 UTF-8

检测与处理示例

检测与处理示例
head -c 3 file.txt | xxd            # 输出 efbbbf 说明带 UTF-8 BOM
file file.txt                       # 部分系统会直接标注 with BOM
sed -i '1s/^\xEF\xBB\xBF//' file.txt   # 仅在文件首剥离 BOM(慎用,先备份)
python -c "print(open('file.txt', encoding='utf-8-sig').readline())"   # utf-8-sig 自动吃掉 BOM
python -c "b=open('file.txt','rb').read(3); print(b == b'\xef\xbb\xbf')"  # 二进制层判定
# PowerShell 侧判断首三字节,避免把 BOM 当正文
powershell -Command "(Get-Content file.txt -Encoding Byte -TotalCount 3) -join ','"

编码与 BOM 字节

编码BOM 字节是否必要
UTF-8EF BB BF不必要,规范建议不加
UTF-16 小端FF FE无外部声明时需要
UTF-16 大端FE FF无外部声明时需要
UTF-32 小端FF FE 00 00无外部声明时需要
UTF-32 大端00 00 FE FF无外部声明时需要
不要全局删除所有 U+FEFF:文件开头的才是 BOM,出现在正文中间的 U+FEFF 是零宽不换行空格,可能是有意插入的排版字符,删掉会改变文本内容。剥离操作应限定在「文件首个字符」。
JSON 规范要求实现不得添加 BOM(可以忽略已存在的 BOM);HTTP 消息头与状态行按字符集定义不允许出现 BOM;Unix shell 脚本带 BOM 会导致内核无法识别 shebang。这些场景都应保存为「UTF-8 无 BOM」。
Windows 生态与 Unix 生态对 BOM 的习惯不同:Windows 工具偏好带 BOM 以便自动识别,Unix 工具链普遍把 BOM 当普通字节。跨平台协作时明确约定「UTF-8 无 BOM」是最省事的做法,代码仓库还应加 .gitattributes 或编辑器配置来固定。

易错点

  • 在 shell 脚本开头留下 BOM:解释器报文件不存在或命令未找到,脚本完全无法执行 → 保存为 UTF-8 无 BOM 并确认首字节为 0x23
  • 把 BOM 当正文第一个字符:首行字符串比较失败、正则首锚定不匹配、JSON 解析报错 → 读取时用能识别 BOM 的接口或手动剥离
  • 用替换命令在整文件范围删除 BOM 字节:正文中合法的 U+FEFF 被一并清除,文本语义被改动 → 只处理文件头,且操作前备份
  • 给 JSON/HTTP 正文加 BOM:下游严格解析器直接报错 → 这类场景固定 UTF-8 无 BOM
  • 在文件中间拼接时保留第二份 BOM:内容里出现零宽字符,肉眼不可见却导致比较失败 → 合并前统一剥离,写出时统一不加 BOM

数据来源与参考

  • RFC 3629:UTF-8 与 BOM 的使用建议
  • RFC 8259:JSON 数据交换格式(BOM 相关条款)
  • Unicode 官方:Byte Order Mark 说明与 U+FEFF 语义

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

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