2012-06-02 138 views
1

我在Python中的字符串遇到了一些问题,而我认为它们应该是==,我相信它与编码的方式有关。基本上,我解析了存储在zip压缩文件中的一些以逗号分隔的值(专门针对那些好奇的GTFS源)。Python字符串编码和==

我在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存档,但不适用于其他人。我做了一些研究,并尝试印刷repr(部分),我得到'\ xef \ xbb \ xbfagency_id'而不是'agency_id'。有谁知道这里发生了什么,以及我如何修复它?感谢所有的帮助!

+0

对不起打开它!当你做到这一点时,我正在编辑过程中! – jmetz

+0

请注意,如果代码仅在第一次(或最后一次)迭代中执行,则在循环之前(或之后)移动该代码的性能和清晰度会更高。此外,您可以使用'position = lineparts.index('agency_id')'在一行中查找所需字段的位置,并使用'for agency_file'中的代理线来循环访问文件中的其余行。一旦您的程序正确运行,您可能需要将其发布到[codereview.SE](http://codereview.stackexchange.com/)以获取更多反馈。 – outis

+0

UTF-8文件不应该有BOM:它们是Unicode标准“既不要求也不推荐”的。这闻起来像一个Windows错误。 – tchrist

回答

5

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

import codecs 

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

python 3.2.3和2.7.3测试 – Kjir

+0

我得到以下错误:UnicodeDecodeError:'ascii'编解码器无法解码位置0中的字节0xef:序号不在范围内(128) – jmetz

+0

与python版本2.7.2+ – jmetz

3

输入文件似乎是UTF8并用'ZERO WIDTH NO-BREAK SPACE'个字符数开始,

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

其被用作一个BOM(或更准确地识别文件为UTF8,如字节顺序ISN用utf8真的不准确,但它通常称为BOM)

+0

BOM具有与零宽度nbsp;相同的十六进制代码。这可能是一个BOM。 – beerbajay

0

简单:你的一些ZIP压缩文件打印的Unicode BOM (Byte Order Mark)在字符串的开头。这用于指示用于多字节编码的字节顺序。这意味着你正在以一个字符串读取一个Unicode字符串(可能是UTF-16编码)。最简单的事情就是在字符串开头检查它并将其删除。

0

你得到的是一个文件,偶尔在文件的前面有一个Unicode Byte Order标记。有时这是编辑引入的,用于表示编码。

这里的一些细节 - 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")) 
+0

这样做给我一个readline()的“NotImplementedError” – jmetz