代码之家  ›  专栏  ›  技术社区  ›  Carl Meyer

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

  •  12
  • Carl Meyer  · 技术社区  · 17 年前

    我正在编写一个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
    

    该问题仅在以下情况下出现: 最后的 一行中的一列。不幸的是,这种情况存在于我的数据集中。我接受了Tanj的解决方案:手动分配一个非打印字符( "\x07" BEL )正如语录所说。这很老套,但它奏效了,我还没有看到另一种可行的解决方案。以下是该解决方案的实际演示:

    >>> 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 回复  |  直到 11 年前
        1
  •  13
  •   Tanj    17 年前

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

        2
  •  3
  •   Kenan Banks    17 年前

    我用Python 2.4.3尝试了几个例子,它似乎足够聪明,可以检测到字段未被引用。

    我知道你已经接受了一个(有点古怪的)答案,但你有没有试着离开 reader.dialect.quotechar 价值独?如果你这样做会怎么样?

    我们能得到示例输入吗?

        3
  •  0
  •   Mark Roddy    17 年前

    +1适用于Triplech

    确认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']