有人可以帮我处理字节顺序标记( BOM )字节与XHTML文件第一行中的UTF8字符吗?
我将XHTML文件打开为UTF8文本:
inputTopicFile = open(inputFileName, "rt", encoding="utf8")
如此十六进制编辑器所示,该UTF8编码的XHTML文件的第一行以三字节UTF8 BOM EF BB BF
开头:
我想从我认为相当于字符串中的三个初始字符位置[0:2]
的内容中删除UTF8 BOM。所以我尝试了这个:
firstLine = firstLine[3:]
无效 - 字符<?
不再出现在结果行的开头。
所以我做了这个实验:
for charPos in range(0, 3):
print("charPos {0} == {1}".format(charPos, firstLine[charPos]))
打印出来:
charPos 0 ==
charPos 1 == <
charPos 2 == ?
然后我将.encode
添加到该循环中,如下所示:
for charPos in range(0, 3):
print("charPos {0} == {1}".format(charPos, eachLine[charPos].encode('utf8')))
哪位给了我:
charPos 0 == b'\xef\xbb\xbf'
charPos 1 == b'<'
charPos 2 == b'?'
显然Python 3以某种方式“知道”3字节BOM是单个非字符数据单元吗?这意味着人们不能尝试处理行中的前三个8位字节(?),就好像它们是UTF8字符一样?
此时我知道我可以通过指定firstLine = firstLine[1:]
来“欺骗”我的代码。但这样做似乎是错误的(?)
那么在仅处理UTF8字符的过程中丢弃UTF8字符串中前三个BOM字节的正确方法是什么?
编辑:根据Anthony Sottile发表的评论,解决方案在我打开源XHTML文件时就像使用encoding="utf-8-sig"
一样简单:
inputTopicFile = open(inputFileName, "rt", encoding="utf-8-sig")
剥离了BOM。瞧!
答案 0 :(得分:1)
正如您在编辑中提到的那样,您可以使用utf8-sig
编码打开文件,但要回答您的问题原因:
Python 3区分字节字符串(具有b
前缀的字符串)和字符串(不带b
前缀),以及尽可能使用字符串。字节字符串与实际字节一起使用;字符串与Unicode代码点一起使用。 BOM是单个代码点,U + FEFF,因此在常规字符串中,Python 3会将其视为单个字符(因为 是单个字符)。当您调用encode
时,将字符串转换为字节字符串。
因此,您所看到的结果正是您应该拥有的结果:Python 3确实知道什么算作单个字符,只有在您调用encode
之后才能看到它。