BOM 字符复制到 JSON in Python 3
BOM character copied into JSON in Python 3
在我的应用程序中,用户可以上传文件(文本文件),我需要读取它并为另一个 API 调用构造 json 对象。
我用
打开文件
f = open(file, encoding="utf-8")
获取第一个词并构造Json对象,...
我的问题是某些文件(尤其是来自Microsoft 环境的文件)开头有BOM 对象。问题是我的 Json 现在里面有这个字符
{
"word":"\ufeffMyWord"
}
当然,API 从此时起不再工作。
我显然错过了什么,因为,utf-8 不应该删除 BOM 对象吗? (因为它不是 utf-8-sig)。
如何克服这个问题?
不,UTF-8 标准没有定义 BOM 字符。这是因为 UTF-8 没有像 UTF-16 和 UTF-32 那样的字节顺序歧义问题。 Unicode 联盟不建议在 UTF-8 编码文件的开头使用 U+FEFF,而如果存在指定编解码器的替代方案,IETF 会积极反对。来自 Wikipedia article on BOM usage in UTF-8:
The Unicode Standard permits the BOM in UTF-8, but does not require or recommend its use.
[...]
The IETF recommends that if a protocol either (a) always uses UTF-8, or (b) has some other way to indicate what encoding is being used, then it "SHOULD forbid use of U+FEFF as a signature."
Unicode 标准只有 'permits' BOM,因为它是一个常规字符,就像其他字符一样;它是一个零宽度的不间断 space 字符。因此,Unicode 联盟建议在解码时不要删除它,以保留信息(以防它有不同的含义,或者你想保持与已经依赖的工具的兼容性)它)。
您有两个选择:
先去掉字符串,U+FEFF被认为是白色的space所以用str.strip()
去掉。或者明确地去掉 BOM:
text = text.lstrip('\ufeff') # remove the BOM if present
(从技术上讲,这将删除任意数量的零宽度不间断 space 字符,但这可能正是您想要的)。
改为使用 utf-8-sig
编解码器打开文件。添加该编解码器是为了处理此类文件,在解码之前从开头明确删除 UTF-8 BOM 字节序列(如果存在)。它可以处理没有这些字节的文件。
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"
在我的应用程序中,用户可以上传文件(文本文件),我需要读取它并为另一个 API 调用构造 json 对象。
我用
打开文件f = open(file, encoding="utf-8")
获取第一个词并构造Json对象,...
我的问题是某些文件(尤其是来自Microsoft 环境的文件)开头有BOM 对象。问题是我的 Json 现在里面有这个字符
{
"word":"\ufeffMyWord"
}
当然,API 从此时起不再工作。
我显然错过了什么,因为,utf-8 不应该删除 BOM 对象吗? (因为它不是 utf-8-sig)。
如何克服这个问题?
不,UTF-8 标准没有定义 BOM 字符。这是因为 UTF-8 没有像 UTF-16 和 UTF-32 那样的字节顺序歧义问题。 Unicode 联盟不建议在 UTF-8 编码文件的开头使用 U+FEFF,而如果存在指定编解码器的替代方案,IETF 会积极反对。来自 Wikipedia article on BOM usage in UTF-8:
The Unicode Standard permits the BOM in UTF-8, but does not require or recommend its use.
[...]
The IETF recommends that if a protocol either (a) always uses UTF-8, or (b) has some other way to indicate what encoding is being used, then it "SHOULD forbid use of U+FEFF as a signature."
Unicode 标准只有 'permits' BOM,因为它是一个常规字符,就像其他字符一样;它是一个零宽度的不间断 space 字符。因此,Unicode 联盟建议在解码时不要删除它,以保留信息(以防它有不同的含义,或者你想保持与已经依赖的工具的兼容性)它)。
您有两个选择:
先去掉字符串,U+FEFF被认为是白色的space所以用
str.strip()
去掉。或者明确地去掉 BOM:text = text.lstrip('\ufeff') # remove the BOM if present
(从技术上讲,这将删除任意数量的零宽度不间断 space 字符,但这可能正是您想要的)。
改为使用
utf-8-sig
编解码器打开文件。添加该编解码器是为了处理此类文件,在解码之前从开头明确删除 UTF-8 BOM 字节序列(如果存在)。它可以处理没有这些字节的文件。
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"