我必须写一个非常定制的类似CSV的解析器。我在Github上找过一些开源的,但没有找到符合我需求的。我可以解决这个问题,但我的问题是,如果在Swift中把它作为一个TopLevelDecoder来实现,是否会完全违反keyvalue解码。
我有键,但不完全是键值对。在CSV文件中,而是每列数据都有一个key。
我需要解析的文件存在一些问题。
//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字段就不行了,因为可以有从零到多的兄弟姐妹。因此,我将不得不使用一个数组。
但在某些情况下,我会将其分割成两个字段。
## 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 {
)
我还没有决定在协议中要有什么,如果有的话.它可能通过像例子中那样让它为空,然后让我的解码器符合它,那么它可能不会是一个非常大的违反键值解码。
先谢谢你了!
CSV文件可以使用正则表达式进行解析。为了让你开始,这可能会节省一些时间。很难知道你真正需要的是什么,因为看起来有很多不同的情况,它可能会发展到更多的情况?
解析CSV文件中一行的Regex表达式可能是这样的 (?:(?:"(?:[^"]|"")*"|(?<=,)[^,]*(?=,))|^[^,]+|^(?=,)|[^,]+$|(?<=,)$)
下面用一个javascript示例来详细描述它的工作原理。建立一个CSV分析器