Pyparsing、Python 3和Unicode字节顺序标记

3
我有一个文本文件,它是UTF-8编码,并且带有字节顺序标记 - 也就是说,前几个字节是EF BB BF 0D 0A 4D...(它是由VS 2013生成的Visual Studio解决方案文件)。
我正在尝试使用PyParsing解析此文件,使用parseFile()方法和Python 3。在Python 2中,我可以这样做:
import pyparsing as pp
bom = pp.Optional(unicode(unichr(0xfeff)).encode('utf-8')).suppress()

为了获取可选的字节顺序标记,但在Python 3中,unicodeunichr 函数已经消失,因为所有字符串都是Unicode。因此,我尝试了以下方法:

bom = pp.Optional(chr(0xfeff)).suppress()

并且这个:

bom = pp.Optional('\ufeff').suppress()

但是两者都不匹配文件开头。我已经搜索了一段时间,但似乎找不到任何相关的内容。

我该如何匹配(或忽略!)Unicode字节顺序标记?


Visual Studio解决方案文件不是XML吗? - Wayne Werner
嗯,我看的不是那个。项目文件肯定是的,但解决方案文件不是。 - Tom
2个回答

4

使用 utf_8_sig 编码类型打开文件:

p.parseFile(open('filename.sln', encoding='utf_8_sig'))

如果存在BOM,则将其抑制。

来自codecs模块:

在编码时,UTF-8编码的字节前面会添加BOM。对于有状态编码器,这只会在第一次写入字节流时执行一次。在解码时,数据开头的可选UTF-8编码的BOM将被跳过。


2

看起来问题在于使用 parseFile() 方法读取文件时所使用的默认编码是 ASCII,因此 UTF-8 编码的字节顺序标记不会以 U+FEFF 结尾,而是以 ASCII 的 EF BB BF 结尾。要避免这个问题,你可以显式打开文件并指定编码。 可以改为:

p.parseFile('filename.sln')

请执行以下操作:

p.parseFile(open('filename.sln', encoding='utf-8'))

然后可以使用以下解析器跳过字节顺序标记:
bom = pp.Optional(chr(0xfeff)).suppress()

1
或者打开文件,使用.read()读取内容,然后调用parseString - parseFile只是对parseString的最小便利包装。 - PaulMcG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接