【问题标题】:parsing CSV files backwards向后解析 CSV 文件
【发布时间】:2010-11-19 07:53:34
【问题描述】:

我有以下格式的 csv 文件:

CSV FILE
"a"             , "b"     , "c" , "d"
hello, world    , 1       , 2   , 3
1,2,3,4,5,6,7   , 2       , 456 , 87
h,1231232,3     , 3       , 45  , 44

问题是第一个字段中有逗号“,”。我无法控制文件的生成,因为这是我收到它们的格式。有没有办法从行尾到开头向后读取 CSV 文件?

如果我被引导到正确的方向,我不介意为此编写一个小 Python 脚本。

【问题讨论】:

  • 为了清楚起见,也许他让它看起来像固定长度的字段?如果第一个字段包含没有任何引号字符的分隔符,则不是格式非常好的 CSV。
  • 这不是 CSV。因此,您不能使用任何 CSV 解析技术。它是其他格式,碰巧有一些逗号,但绝对不是 CSV 在任何意义上。请停止将其称为 CSV。称之为“类 CSV”或“随机逗号值”。

标签: python parsing csv readline


【解决方案1】:

你总是可以用正则表达式做一些事情,比如 (perl regex)

#!/usr/bin/perl

use IO::File;

if (my $file = new IO::File("test.csv"))
{
    foreach my $line (<$file>) {
    $line =~ m/^(.*),(.*?),(.*?),(.*?)$/;
    print "[$1][$2][$3][$4]\n";
    }
} else {
    print "Unable to open test.csv\n";
}

(第一个是贪心搜索,后三个不是) 编辑:发布完整代码而不仅仅是正则表达式

【讨论】:

    【解决方案2】:

    先反转字符串再处理。

    tmp = tmp[::-1]

    【讨论】:

      【解决方案3】:

      rsplit 字符串方法从右侧而不是左侧开始拆分字符串,因此它可能就是您要查找的内容(它需要一个指定最大拆分次数的参数):

      line = "hello, world    , 1       , 2   , 3"
      parts = line.rsplit(",", 3)
      print parts  # prints ['hello, world    ', ' 1       ', ' 2   ', ' 3']
      

      如果您想从拆分列表中的每个项目的开头和结尾去除空格,那么您可以使用带有列表理解的strip 方法

      parts = [s.strip() for s in parts]
      print parts  # prints ['hello, world', '1', '2', '3']
      

      【讨论】:

        【解决方案4】:

        从您提供的示例中,“列”看起来是固定大小的。首先(带逗号的那个)是 16 个字符长,那么为什么不尝试逐行读取文件,然后为每一行读取前 16 个字符(作为第一列的值),然后相应地读取其余的?获得每个值后,您可以进一步解析它(修剪空格等...)。

        【讨论】:

          【解决方案5】:

          那不是 CSV 文件,逗号分隔的意思就是这样。

          你怎么能确定那不是:

          CSV FILE
          "a"             , "b"     , "c" , "d"
          hello           , world   , 1   , 2   , 3
          1               , 2       , 3   , 4   , 5,6,7,2,456,87
          h               , 1231232 , 3   , 3   , 45,44
          

          如果文件如您所指,那么第一组应该用引号括起来,看起来字段名称很奇怪,以至于包含逗号的字段不是。

          我不喜欢从源头上修复错误,如果他们声称是这样,我会退回到数据生成器以提供正确的 CSV。

          【讨论】:

          • 好点,但我确定格式,因为我是 100%,因为最后三列是 int 类型。我们按原样接收文件。我们无法控制这一代。见鬼,我什至不确定他们用什么来生成它们
          • 我最喜欢的一句话是“我喜欢 IT 标准……有很多选择!”缺少的是,即使在选择了众多标准中的一个之后,仍有一百万种方法可以将其弄乱。很高兴看到您找到了解决方案,我也非常喜欢 Regex 解决方案,但它在处理器方面会很昂贵(老 Perl 程序员对 regex 情有独钟)。祝您处理顺利!
          【解决方案6】:

          如果您总是希望列数相同,并且只有第一列可以包含逗号,则只需读取任何内容并在开头连接多余的列。

          问题在于界面不明确,您可以尝试绕过它,但更好的解决方案是尝试修复界面(这通常比创建多个补丁更难......)。

          【讨论】:

            【解决方案7】:

            我同意啤酒先生。那是一个格式错误的 csv 文件。您最好的选择是找到其他分隔符或停止重载逗号或引用/转义非字段分隔逗号

            【讨论】:

              【解决方案8】:

              我不完全理解您为什么要反向阅读每一行,但您可以这样做:

              import csv
              file = open("mycsvfile.csv")
              reversedLines = [line[::-1] for line in file]
              file.close()
              reader = csv.reader(reversedLines)
              for backwardRow in reader:
                  lastField = backwardRow[0][::-1]
                  secondField = backwardRow[1][::-1]
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-08-25
                • 1970-01-01
                • 2016-09-16
                • 2011-04-25
                • 2016-05-04
                • 2013-11-23
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多