Python字符串编码和==

时间:2012-06-02 17:38:45

标签: python string utf-8

我认为python中的字符串不是==时遇到麻烦,我认为它们应该是,我相信它与编码方式有关。基本上,我解析了一些存储在zip存档中的逗号分隔值(特别是对于那些好奇的人来说,GTFS提要)。

我在python中使用ZipFile模块打开zip存档的某些文件,然后将其中的文本与某些已知值进行比较。这是一个示例文件:

agency_id,agency_name,agency_url,agency_phone,agency_timezone,agency_lang
ARLC,Arlington Transit,http://www.arlingtontransit.com,703-228-7433,America/New_York,en

我正在使用的代码是尝试在文本的第一行中识别字符串“agency_id”的位置,以便我可以在任何后续行中使用相应的值。以下是代码片段:

zipped_feed = ZipFile(feed_name, "r")
agency_file = zipped_feed.open("agency.txt", "r")

line_num = 0
agencyline = agency_file.readline()
while agencyline:
    if line_num == 0:
        # this is the header, all we care about is the agency_id
        lineparts = agencyline.split(",")
        position = -1
        counter = 0
        for part in lineparts:
            part = part.strip()
            if part == "agency_id":
                position = counter              
        counter += 1
        line_num += 1
        agencyline = agency_file.readline()
    else:
        .....

此代码适用于某些zip存档,但不适用于其他zip存档。我做了一些研究,并尝试打印repr(部分),我得到'\ xef \ xbb \ xbfagency_id'而不是'agency_id'。有谁知道这里发生了什么以及我如何解决它?谢谢你的帮助!

4 个答案:

答案 0 :(得分:5)

这是一个Byte Order Mark,它告诉文件的编码,在UTF-16和UTF-32的情况下,它也告诉文件的endianess。您可以解释它或检查它并从字符串中删除它。 要删除它,你可以这样做:

import codecs

unicode(part, "utf8").lstrip(codecs.BOM_UTF8.decode("utf8", "strict"))

答案 1 :(得分:3)

您的输入文件似乎是utf-8,以'ZERO WIDTH NO-BREAK SPACE' - 字符

开头
import unicodedata
unicodedata.name('\xef\xbb\xbf'.decode('utf8'))
# gives: 'ZERO WIDTH NO-BREAK SPACE'

用作BOM(或者更准确地将文件识别为utf8,因为utf8的字节顺序不是很准确,但它通常被称为BOM)

答案 2 :(得分:0)

简单:您的一些zip存档正在字符串的开头打印Unicode BOM (Byte Order Mark)。这用于指示用于多字节编码的字节顺序。这意味着您正在读取Unicode字符串(可能是UTF-16编码)作为字节串。最容易做的事情是在字符串的开头检查它并将其删除。

答案 3 :(得分:0)

您所拥有的文件可能偶尔会在文件的前面有一个Unicode字节顺序标记。有时这是由编辑引入来表示编码。

以下是一些详情 - http://en.wikipedia.org/wiki/Byte_order_mark

底线是您可以查找\ xef \ xbb \ xbf字符串,该字符串是UTF-8编码数据的标记,只是将其剥离。或者另一种选择是使用编解码器包打开它

with codecs.open('input', 'r', 'utf-8') as file: 

或在你的情况下

zipped_feed = ZipFile(feed_name, "r")
# adding a StreamReader around the zipped_feed.open(...)
agency_file = codecs.StreamReader(zipped_feed.open("agency.txt", "r"))