人们一直在问这个问题是什么,所以我会尝试总结一下 - 我正在努力实现检测解析CSV文件的最佳匹配格式的方法。这可能是我想要做的最好的描述。
我的csv文件包含以下内容:
710000 8454889 03 3 ;sometext;;48,05;65,82;;65,82
710001 8454889 03 3 ;sometext;;49,09;66,96;;66,96
710002 8454889 03 3 ;sometext;;12,63;17,22;;17,22
没有引号和“;”作为分隔符。
我已经描述了几种csv阅读器方言:
csv.register_dialect('excel', delimiter = ',', quotechar = '"', quoting = csv.QUOTE_ALL, strict = True, skipinitialspace = True)
csv.register_dialect('semicolonquotes', delimiter = ';', quotechar = '"', quoting = csv.QUOTE_ALL, strict = True, skipinitialspace = True)
csv.register_dialect('semicolonnonquotes', delimiter = ';', quotechar = None, quoting = csv.QUOTE_NONE, strict = True, skipinitialspace = True)
我有脚本试图找出哪些格式与文件内容最匹配。不幸的是,在这个示例文件的情况下,它匹配第一种情况 - “excel”,即使我希望它只匹配“分号方式”。
修改 我用来匹配文件的代码很像这样:
dialects = csv.list_dialects()
for dialect in dialects:
file.seek(0)
reader = csv.reader(file, csv.get_dialect(dialect))
reader.next()
非常简单的代码,用于查看读者在使用set dialect读取时是否抛出错误。包含在try / except中以便无误地捕获第一个方言。不幸的是,这些方言都没有引起错误。
/修改
我认为如果我将strict(link)设置为True,那么当行不包含引号时,它会引发错误。但显然它并不像那样。
第一个方言匹配,并获得csv行,如:
['710000 8454889 03 3 ;sometext;;48', '05;65', '82;;65', '82']
有没有办法调整这个,所以我会得到我想要的结果:
['710000 8454889 03 3 ', 'sometext', '', '48,05', '65,82', '', '65,82']
EDIT2
通过文档阅读似乎指定csv.reader的引用几乎没有:http://docs.python.org/2.7/library/csv.html#csv.QUOTE_ALL
猜猜这是我的问题所在。
/ EDIT2
免责声明:我知道CSV代表COMMA分隔值。如果在没有扩展现有库的情况下无法实现我想要的目标,那么我将接受这个作为答案并强制用户使用仅包含逗号作为分隔符的CSV文件。
答案 0 :(得分:0)
我不确定我明白你在问什么。但是,如果您知道分隔符是什么并且没有引用,请忘记csv方言,并将这些内容指定为创建的csv.reader
实例的格式化参数:
with open('contents.csv', 'rb') as file:
reader = csv.reader(file, delimiter=';', quotechar=None)
line = reader.next()
print 'line 1: {}'.format(line)
输出:
line 1: ['710000 8454889 03 3 ', 'sometext', '', '48,05', '65,82', '', '65,82']
答案 1 :(得分:0)
我认为如果你想让脚本自动找出要使用的最好的csv方言,你不应该根据是否会抛出错误,而是某种方言的表现如何(如果有的话。)
"最" CSV将在每行中具有相似数量的列(通常将第一行作为标题)。您可以使用此假设来构建测试用例,以测试每个方言中每行的列数[列表长度]的方差。解析所有行或较小样本后,列数(或最高重复计数)方差最小的方言应该是最好的。如果有平局,你可能不得不想出更多的诡计,但这应该给你一个起点。
只要知道一旦你开始收到任何顺序的csv,那么这个假设就会失败。实际上这一直在发生。