在Swift中解码解析CSV和类似CSV的文件。

问题描述 投票:0回答:1

我必须写一个非常定制的类似CSV的解析器。我在Github上找过一些开源的,但没有找到符合我需求的。我可以解决这个问题,但我的问题是,如果在Swift中把它作为一个TopLevelDecoder来实现,是否会完全违反keyvalue解码。

我有键,但不完全是键值对。在CSV文件中,而是每列数据都有一个key。

我需要解析的文件存在一些问题。

  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字段就不行了,因为可以有从零到多的兄弟姐妹。因此,我将不得不使用一个数组。

但在某些情况下,我会将其分割成两个字段。

  1. 我需要解析的所有文件都不是严格意义上的CSV文件。所有的文件都有表格数据(逗号或制表符分隔),但有些文件有几行注释(有时包含元数据),我需要考虑。这些文件的扩展名是.txt,而不是.csv。
## File generated 2020-05-02
"Name", "Parents","Siblings"
"Danny", "Margaret, John","Mike, Jim, Jane"

因此,我需要偷看第一行来确定是否有这样的注释,在解析了这行之后,我可以继续将文件的其余部分作为CSV处理。

我计划让它看起来像任何解码器,从应用程序的角度来看,但在我的解码器内部,我可以处理的事情,就像他们是一个键值对,因为只有一组键,这是文件中的第一行,如果没有注释在开始。不过我还是想使用CodingKeys。

你有什么想法?我应该以解码器的形式实现进去(其实就是Swift中的TopLevelDecoder),还是会滥用键值解码的思想?另一种选择是将其作为一个解析器来实现,但我必须处理几种类型的文件(JSON、GraphQL、CSV和类似CSV的文件),我认为如果我可以为所有类型的文件使用解码器,我的应用程序代码会简单很多。

对于JSON没有问题,因为在Swift中已经有一个HSON解码器。对于GraphQL也没有问题,因为我可以用一个无键容器写一个解码器。问题文件是那些CSV和类似CSV的文件。

其中有些文件的所有内容都用双引号,但CSV头和值的 "键 "用双引号。有些文件只有键值用双引号,但没有值。有些字段用逗号分隔,有些用制表符分隔。有的字段内有逗号,需要特殊处理。有些文件的开头有注释,需要跳过,然后再将文件的其余部分解析为CSV。

有些文件的第一列有两个字段。我对这些文件的格式没有任何影响,所以我只能处理它。

如果你想知道它们是什么文件,我可以告诉你,它们是原始DNA的文件,与DNA匹配的文件,与我有匹配DNA的人的共同DNA片段的文件。这是不少略有不同的文件,来自几家DNA检测公司。我希望他们都用标准格式的JSON,所有的键也是所有公司的标准格式。但他们都有不同的CSV头,以及其他的差异。

我还要解码Gedcom文件,也算是有键值编码对,但这种格式也不符合文件中的纯键值编码。

另外。我找过其他有类似问题的人,但不完全一样,所以我不想劫持他们的帖子。请看这个帖子 关于从CSV > JSON > Swift对象的建议。

这更多的是一个问题,如何在Swift中从CSV转换为JSON,再转换为内部数据结构。我知道我可以写一个解析器来解决这个问题,但我认为用解码器来处理所有这些文件会更优雅,但我想知道你的想法。

我也在想做一个新的协议

protocol ColumnCodingKey: CodingKey {
)

我还没有决定在协议中要有什么,如果有的话.它可能通过像例子中那样让它为空,然后让我的解码器符合它,那么它可能不会是一个非常大的违反键值解码。

先谢谢你了!

swift csv parsing decoding key-value-coding
1个回答
0
投票

CSV文件可以使用正则表达式进行解析。为了让你开始,这可能会节省一些时间。很难知道你真正需要的是什么,因为看起来有很多不同的情况,它可能会发展到更多的情况?

解析CSV文件中一行的Regex表达式可能是这样的 (?:(?:"(?:[^"]|"")*"|(?<=,)[^,]*(?=,))|^[^,]+|^(?=,)|[^,]+$|(?<=,)$)

下面用一个javascript示例来详细描述它的工作原理。建立一个CSV分析器

© www.soinside.com 2019 - 2024. All rights reserved.