BOM字符在Python 3中复制到JSON中

Mar*_*vec 1 python byte-order-mark file utf-8 python-3.x

在我的应用程序内部,用户可以上传文件(文本文件),我需要读取它并为另一个API调用构造json对象。

我用打开文件

f = open(file, encoding="utf-8")
Run Code Online (Sandbox Code Playgroud)

得到第一个单词并构造Json对象,...

我的问题是,某些文件(尤其是来自Microsoft环境的文件)在开始时具有BOM对象。问题是我的Json现在里面有这个角色

{
   "word":"\\ufeffMyWord"
}
Run Code Online (Sandbox Code Playgroud)

当然,此后API仍无法使用。

我显然错过了一些事情,因为utf-8是否不应该删除BOM表对象?(因为它不是utf-8-sig)。

如何克服呢?

Mar*_*ers 5

不可以,UTF-8标准没有定义BOM字符。这是因为UTF-8没有像UTF-16和UTF-32这样的字节顺序歧义问题。Unicode联合会不建议在UTF-8编码文件的开头使用U + FEFF,而IETF会积极劝阻它,如果存在指定编解码器的替代方法。摘自Wikipedia有关UTF-8中BOM使用的文章

Unicode标准允许使用UTF-8中的BOM,但不要求也不建议使用它。

[...]

IETF建议,如果协议(a)始终使用UTF-8,或者(b)使用某种其他方式指示正在使用哪种编码,则该协议“应禁止使用U + FEFF作为签名”。

Unicode标准仅允许使用BOM,因为它是常规字符,就像其他字符一样。这是一个零宽度的不间断空格字符。因此,Unicode联合会建议在解码时不要删除它,以保留信息(以防它具有不同的含义,或者您想保持与依赖它的工具的兼容性)。

您有两种选择:

  • 首先去除字符串,U + FEFF被认为是空格,因此用删除str.strip()。或明确地只是去除BOM表:

    text = text.lstrip('\ufeff')  # remove the BOM if present
    
    Run Code Online (Sandbox Code Playgroud)

    (从技术上讲,这将删除任意数量的零宽度不间断空格字符,但是无论如何,这可能都是您想要的)。

  • utf-8-sig而是使用编解码器打开文件。添加了该编解码器以处理此类文件,在解码之前从头开始显式删除了UTF-8 BOM字节序列。它适用于没有这些字节的文件。