Pyparsing, Python 3 和 Unicode 字节序标记

Pyparsing, Python 3 and the Unicode byte order mark

我有一个 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 字节顺序标记?

这里的问题似乎是使用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()

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

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

BOM 如果存在,将被隐藏。

来自编解码器模块:

On encoding a UTF-8 encoded BOM will be prepended to the UTF-8 encoded bytes. For the stateful encoder this is only done once (on the first write to the byte stream). For decoding an optional UTF-8 encoded BOM at the start of the data will be skipped.