代码之家  ›  专栏  ›  技术社区  ›  Yin Zhu

如何读取csv行?

  •  5
  • Yin Zhu  · 技术社区  · 16 年前

    可以使用字符串拆分函数生成一条普通的csv行。但有些线路可能 " ,例如

    "good,morning", 100, 300, "1998,5,3"
    

    因此,直接使用字符串拆分无法解决问题。

    我的解决方案是首先使用 , 然后将字符串与 在那时,字符串的开始或结束。

    这个问题的最佳实践是什么?

    我对是否有一个python或f代码片段感兴趣。

    编辑: 我对实现细节更感兴趣,而不是使用库。

    4 回复  |  直到 16 年前
        1
  •  9
  •   Rafał Dowgird    16 年前

    有一个 csv python中的模块,用于处理此问题。

    编辑 :此任务属于“构建lexer”类别。完成这些任务的标准方法是构建一个状态机(或者使用一个Lexer库/框架来完成这些任务)。

    此任务的状态机可能只需要两个状态:

    • 第一个字符,它读取除逗号和换行符以外的每个字符作为字段的一部分(例外:前导空格和尾随空格)、逗号作为字段分隔符、换行符作为记录分隔符。当它遇到开场白时,它会进入
    • 读引号字段状态,其中除引号之外的每个字符(包括逗号和换行符)都被视为字段的一部分,不后跟引号的引号表示读引号字段的结束(返回初始状态),后跟引号的引号被视为单引号(转义引号)。

    顺便说一下,您的连接解决方案将在 "Field1","Field2" "Field1"",""Field2" .

        2
  •  3
  •   Adam Matan    16 年前

    python's CSV module :

    读取普通csv文件:

    import csv
    reader = csv.reader(open("some.csv", "rb"))
    for row in reader:
        print row
    

    读取具有备用格式的文件:

    import csv
    reader = csv.reader(open("passwd", "rb"), delimiter=':', quoting=csv.QUOTE_NONE)
    for row in reader:
        print row
    

    有一些 nice usage examples in LinuxJournal.com .

    如果您对细节感兴趣,请阅读“ split string at commas respecting quotes when string not in csv format “显示与此问题相关的一些很好的regexen,或者简单地读取csv模块源代码。

        3
  •  1
  •   Limbo Peng    16 年前

    程序设计实践第四章 给出了CSV解析器的C和C++实现。

        4
  •  1
  •   Lennart Regebro    16 年前

    一般的实现细节如下(未测试)

    def csvline2fields(line):
        fields = []
        quote = None
        while line.strip():
            line = line.strip()
            if line[0] in ("'", '"'):
                # Find the next quote:
                end = line.find(line[0])
                fields.append(line[1:end])
                # Find the beginning of the next field
                next = line.find(SEPARATOR)
                if next == -1:
                    break
                line = line[next+1:]
                continue
            # find the next separator:
            next = line.find(SEPARATOR)
            fields.append(line[0:next])
            line = line[next+1:]