Декодирование / анализ CSV и CSV-подобных файлов в Swift - PullRequest
0 голосов
/ 03 мая 2020

Мне придется написать очень персонализированный CSV-подобный парсер / декодер. Я искал с открытым исходным кодом на Github, но не нашел ничего, что соответствует моим потребностям. Я могу решить это, но мой вопрос заключается в том, будет ли это полным нарушением декодирования ключ / значение, чтобы реализовать это как TopLevelDecoder в Swift.

У меня есть ключи, но не совсем пары ключ / значение. В файлах CSV есть ключ для каждого столбца данных:

Есть ряд проблем с файлами, которые мне нужно проанализировать:

  1. Запятые не только для разделения полей, но есть также запятые в некоторых полях. Пример:
//If I convert to an array
Struct Family {
    let name: String?
    let parents: [String?]
    let siblings: [String?]
}

В этом примере имена обоих родителей находятся в одном поле и должны быть преобразованы в массив, а также в поле братьев и сестер.

"Name", "Parents","Siblings"
"Danny", "Margaret, John","Mike, Jim, Jane"

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

Struct Family {
    let name: String?
    let mother: String?
    let father: String?
}

, но с полем Siblings, которое не работает, так как может быть все от нуля до многих братья и сестры. Поэтому мне придется использовать массив.

В некоторых случаях я разделяю два поля.

Все файлы, которые мне нужно проанализировать, не являются строго CSV. Все файлы имеют табличные данные (разделенные запятыми или табуляцией), но некоторые из файлов имеют несколько строк комментариев (иногда содержащих метаданные), которые мне нужно рассмотреть. Эти файлы имеют расширение .txt вместо .csv.
## File generated 2020-05-02
"Name", "Parents","Siblings"
"Danny", "Margaret, John","Mike, Jim, Jane"

Поэтому мне нужно посмотреть на первую строку (строки), чтобы определить, есть ли такие комментарии, и после того, как это было проанализировал, я могу продолжать обрабатывать остальную часть файла как CSV.

Я планирую сделать его похожим на любой декодер, с точки зрения приложений, но внутренне в моем декодере я могу обрабатывать вещи, как если бы они были пара ключ / значение, потому что есть только один набор ключей, и это первая строка в файле, если в начале нет комментариев. Я все еще хочу использовать CodingKeys.

Что вы думаете? Должен ли я реализовать в качестве декодера (на самом деле TopLevelDecoder в Swift), или это будет злоупотребление идеей декодирования ключ / значение? Альтернатива состоит в том, чтобы реализовать это как синтаксический анализатор, но мне нужно обрабатывать несколько типов файлов (JSON, GraphQL, CSV и CSV-подобные файлы), и я думаю, что мой код приложения был бы намного проще, если бы я мог использовать декодеры для всех типов файлов.

Для JSON проблем нет, поскольку в Swift уже есть HSON-декодер. Для GraphQL это тоже не проблема, потому что я могу написать декодер с контейнером без ключа. Проблемные файлы - это CSV и CSV-подобные файлы.

Некоторые из них содержат все в двойных кавычках, но для «ключей» в заголовке CSV и для значений. У некоторых есть только двойные кавычки для ключей, но не для значений. У некоторых есть поля, разделенные запятыми, а некоторые - через табуляцию. У некоторых есть запятые в полях, которые требуют специальной обработки. У некоторых есть комментарии в начале файла, которые нужно пропустить, прежде чем анализировать остальную часть файла как CSV.

Некоторые файлы имеют два поля в первом столбце. Я не имею никакого влияния на формат этих файлов, поэтому мне просто нужно разобраться с этим.

Если вам интересно, что это за файлы, я могу сказать, что это файлы необработанной ДНК, файлы с ДНК совпадения, файлы с общими сегментами ДНК с людьми, с которыми у меня совпадает ДНК. Это несколько разных файлов от нескольких компаний, занимающихся тестированием ДНК. Я sh все они использовали JSON в стандартном формате, где все ключи также были стандартными для всех компаний. Но все они имеют разные заголовки CSV и другие различия.

Мне также нужно декодировать файлы Gedcom, которые также имеют пары код / ​​ключ, но этот формат тоже не соответствует чистому ключу / кодирование значений в файлах.

Также: я искал других с похожими проблемами, но не совсем такими же, поэтому я не хотел перехватывать их темы. См. Эту ветку Советы по переходу из CSV> JSON> Swift объекты

Вопрос был скорее в том, как преобразовать из CSV в JSON, а затем во внутренние структуры данных в Swift. Я знаю, что могу написать парсер, чтобы решить эту проблему, но я думаю, что было бы более элегантно обрабатывать все эти файлы с помощью декодеров, но я хочу, чтобы вы подумали об этом.

Я также думал о создании нового протокола

protocol ColumnCodingKey: CodingKey {
)

Я еще не решил, что иметь в протоколе, если что-нибудь. Это может сработать, просто опустошив его, как в примере, и затем пусть мой декодер будет соответствовать ему, тогда, возможно, это не будет серьезным нарушением декодирования ключ / значение.

Заранее спасибо!

1 Ответ

0 голосов
/ 11 мая 2020

CSV-файлы могут быть проанализированы с помощью регулярного выражения. Для начала это может сэкономить время. Трудно понять, что вам действительно нужно, потому что похоже, что есть много разных сценариев ios, может ли он вырасти в еще большее количество ситуаций?

Выражение Regex для анализа одной строки в файле CSV может выглядеть примерно так
(?:(?:"(?:[^"]|"")*"|(?<=,)[^,]*(?=,))|^[^,]+|^(?=,)|[^,]+$|(?<=,)$)

Вот подробное описание того, как он работает с javascript семплом Создание синтаксического анализатора CSV

...