Как прочитать строку CSV с «?

Тривиальную строку CSV можно разделить с помощью функции разделения строк. Но некоторые строки могут иметь ", например.

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

таким образом, прямое использование разделения строк не решит проблему.

Мое решение состоит в том, чтобы сначала разделить строку, используя ,, а затем объединить строки с " в начале или в конце строки.

Какова наилучшая практика для этой проблемы?

Меня интересует, есть ли для этого фрагмент кода Python или F#.

EDIT: меня больше интересуют детали реализации, чем использование библиотеки.


person Yin Zhu    schedule 26.01.2010    source источник


Ответы (4)


В Python есть модуль csv, который обрабатывает это.

Изменить: эта задача относится к категории "создать лексер". Стандартный способ выполнения таких задач — создать конечный автомат (или использовать библиотеку/фреймворк лексера, который сделает это за вас).

Конечному автомату для этой задачи, вероятно, потребуется только два состояния:

  • Начальный, где он читает каждый символ, кроме запятой и новой строки, как часть поля (исключение: начальные и конечные пробелы), запятая как разделитель полей, новая строка как разделитель записи. Когда он встречает открывающую цитату, он переходит в
  • состояние поля чтения в кавычках, где каждый символ (включая запятую и новую строку), за исключением кавычки, рассматривается как часть поля, кавычка, за которой не следует кавычка, означает конец поля чтения в кавычках (возврат к исходному состоянию), после которого следует кавычка by a quote рассматривается как одинарная кавычка (экранированная кавычка).

Кстати, ваше конкатенирующее решение сломается на "Field1","Field2" или "Field1"",""Field2".

person Rafał Dowgird    schedule 26.01.2010
comment
Как и в случае с большинством проблем синтаксического анализа, более устойчивой практикой является использование библиотеки, если она существует. Если OP действительно заинтересован в реализации, я уверен, что библиотека Python имеет открытый исходный код. - person Benjamin Oakes; 26.01.2010
comment
Как мы говорим в сообществе Python: используйте исходный код, Люк. Он полностью открыт и уже установлен вместе с Python. Просто прочитайте это. - person S.Lott; 26.01.2010

Из модуля Python CSV:

чтение обычного файла 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

На LinuxJournal.com есть несколько хороших примеров использования.

Если вас интересуют подробности, прочтите раздел "разделить строку на запятые в кавычках, когда строка не в формате csv», показывающая некоторые хорошие регулярные выражения, связанные с этой проблемой, или просто прочитайте исходный код модуля csv.

person Adam Matan    schedule 26.01.2010

Глава 4 "Практика программирования" содержит реализации парсера CSV на языках C и C++.

person Limbo Peng    schedule 26.01.2010

Общая деталь реализации будет примерно такой (непроверенной)

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:]
person Lennart Regebro    schedule 26.01.2010
comment
На самом деле, рекомендация взглянуть на модуль CSV в открытом исходном коде Python намного лучше. Дурак я. - person Lennart Regebro; 26.01.2010