2017-07-14 21 views
1

在我的应用程序,用户可以上传文件(文本文件),我需要阅读并构建JSON对象另一个API调用。BOM字符复制到JSON在Python 3

我打开与

f = open(file, encoding="utf-8") 

文件中获得的第一个字,构建JSON对象,...

我的问题是,一些文件(特别是来自微软环境)有BOM对象开头。问题是我的Json现在有这个字符

{ 
    "word":"\\ufeffMyWord" 
} 

当然,从这一点API不工作。

我显然错过了什么,因为,不应该UTF-8 BOM删除对象? (因为它不是utf-8-sig)。

如何克服呢?

回答

3

否,UTF-8标准没有定义一个BOM字符。这是因为UTF-8没有像UTF-16和UTF-32这样的字节顺序模糊问题。 Unicode协会不建议使用U + FEFF在UTF-8编码的文件的开头,而IETF积极鼓励它,如果替代指定编解码器存在。从Wikipedia article on BOM usage in UTF-8

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 
    

    (技术上说会移除任何数量的零宽度不间断空格字符,但是这可能是你无论如何要什么)。

  • 打开与utf-8-sig编解码器,而不是文件。该编解码器被添加来处理这些文件,在解码之前明确地从开始删除UTF-8 BOM字节序列(如果存在的话)。它将处理没有这些字节的文件。

+0

很酷,我不知道'utf-8-sig'接受没有BOM的输入。 – lenz

-1

UTF-8没有消除BOM(字节顺序标记)。您必须检查文件是否包含BOM,并将其删除。

if text.startswith(codecs.BOM_UTF8): 
    headers[0] = (headers[0])[3:] 
    print "Removed BOM" 
else: 
    print "No BOM char, Process your file" 
+0

这只适用于**字节串**。请注意,OP使用的是Python 3,而不是Python 2,并且*已经解码了数据*。 –

+0

换句话说,它们的文本以单个代码点“\ ufeff''开始,而不是以3个字节的'b'\ xef \ xbb \ xbf''开头。 –