如何禁用Python 2.4 CSV阅读器中的引用?

时间:2009-01-30 00:22:41

标签: python csv

我正在编写一个Python实用程序,需要解析一个我无法控制的大型,定期更新的CSV文件。该实用程序必须在只有Python 2.4可用的服务器上运行。 CSV文件根本不引用字段值,但Python 2.4 version of the csv library似乎没有给我任何关闭引用的方法,它只允许我设置引号字符(dialect.quotechar = '"'或其他)。如果我尝试将引号字符设置为None或空字符串,则会出现错误。

我可以通过将dialect.quotechar设置为某个“稀有”字符来解决这个问题,但这很脆弱,因为没有ASCII字符我绝对可以保证不会显示在字段值中(分隔符除外) ,但是如果我设置dialect.quotechar = dialect.delimiter,事情就会出现干扰。

Python 2.5 and later中,如果我将dialect.quoting设置为csv.QUOTE_NONE,则CSV阅读器会尊重该值,并且不会将任何字符解释为引号字符。有没有办法在Python 2.4中复制这种行为?

更新:感谢Triptych和Mark Roddy帮助缩小问题范围。这是一个最简单的案例演示:

>>> import csv
>>> import StringIO
>>> data = """
... 1,2,3,4,"5
... 1,2,3,4,5
... """
>>> reader = csv.reader(StringIO.StringIO(data))
>>> for i in reader: print i
... 
[]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
_csv.Error: newline inside string

只有在行的 final 列中有一个双引号字符时,才会出现此问题。不幸的是,我的数据集中存在这种情况。我接受了Tanj的解决方案:手动指定非打印字符("\x07"BEL)作为quotechar。这很hacky,但它确实有效,我还没有看到另一个解决方案。以下是该解决方案的演示:

>>> import csv
>>> import StringIO
>>> class MyDialect(csv.Dialect):
...     quotechar = '\x07'
...     delimiter = ','
...     lineterminator = '\n'
...     doublequote = False
...     skipinitialspace = False
...     quoting = csv.QUOTE_NONE
...     escapechar = '\\'
... 
>>> dialect = MyDialect()
>>> data = """
... 1,2,3,4,"5
... 1,2,3,4,5
... """
>>> reader = csv.reader(StringIO.StringIO(data), dialect=dialect)
>>> for i in reader: print i
... 
[]
['1', '2', '3', '4', '"5']
['1', '2', '3', '4', '5']

在Python 2.5+设置中引用csv.QUOTE_NONE就足够了,quotechar的值将无关紧要。 (我实际上通过csv.Sniffer获取我的初始方言,然后覆盖quotechar值,而不是通过继承csv.Dialect,但我不希望这会分散真正的问题;以上两个会议证明Sniffer不是问题。)

3 个答案:

答案 0 :(得分:13)

我不知道python是否愿意/允许它,但你可以使用不可打印的ascii代码,如BEL或BS(退格)这些我认为非常罕见。

答案 1 :(得分:3)

我尝试了一些使用Python 2.4.3的例子,它似乎很聪明,可以检测到字段是否未加引号。

我知道你已经接受了一个(稍微有些hacky)的答案,但你是否试过单独留下reader.dialect.quotechar值?如果你这样做会怎么样?

我们有机会获得示例输入吗?

答案 2 :(得分:0)

+1为Triptych

确认csv.reader自动处理带引号的csv文件:

>>> import StringIO
>>> import csv
>>> data="""
... 1,2,3,4,5
... 1,2,3,4,5
... 1,2,3,4,5
... """
>>> reader=csv.reader(StringIO.StringIO(data))
>>> for i in reader:
...     print i
... 
[]
['1', '2', '3', '4', '5']
['1', '2', '3', '4', '5']
['1', '2', '3', '4', '5']