【问题标题】:Parse variable length array from csv to struct将可变长度数组从 csv 解析为 struct
【发布时间】:2020-04-08 21:29:40
【问题描述】:

我有以下设置来解析 csv 文件:

package main

import (
    "fmt"
    "os"
    "encoding/csv"
)

type CsvLine struct {
    Id string
    Array1 [] string
    Array2 [] string
}


func ReadCsv(filename string) ([][]string, error) {

    f, err := os.Open(filename)
    if err != nil {
        return [][]string{}, err
    }
    defer f.Close()

    lines, err := csv.NewReader(f).ReadAll()
    if err != nil {
        return [][]string{}, err
    }
    return lines, nil
}


func main() {

    lines, err := ReadCsv("./data/sample-0.3.csv")
    if err != nil {
        panic(err)
    }

    for _, line := range lines {
                fmt.Println(line)
        data := CsvLine{
            Id: line[0],
            Array1: line[1],
            Array2: line[2],
        }
        fmt.Println(data.Id)
        fmt.Println(data.Array1)
        fmt.Println(data.Array2)
    }
}

以及我的 csv 文件中的以下设置:

594385903dss,"['fhjdsk', 'dfjdskl', 'fkdsjgooiertio']","['jflkdsjfl', 'fkjdlsfjdslkfjldks']"
87764385903dss,"['cxxc', 'wqeewr', 'opi', 'iy', 'qw']","['cvbvc', 'gf', 'mnb', 'ewr']"

我的理解是可变长度列表应该被解析成一个切片,是否可以通过 csv 阅读器直接执行此操作? (csv 输出是通过 python 项目生成的。)

感谢您的帮助/建议。

【问题讨论】:

  • 没有。它不是。 CSV 中没有“数组”的官方定义。所以我认为没有任何库支持这种转换。

标签: string csv go slice


【解决方案1】:

CSV 没有“可变长度数组”的概念,它只是一个逗号分隔的值列表。格式在RFC 4180 中进行了描述,这正是encoding/csv 包实现的内容。

您只能从 CSV 行中获取字符串切片。如何解释这些值取决于您。如果您想进一步拆分数据,则必须对数据进行后期处理。

你所拥有的可以简单地用regexp包处理,例如

var r = regexp.MustCompile(`'[^']*'`)

func split(s string) []string {
    parts := r.FindAllString(s, -1)
    for i, part := range parts {
        parts[i] = part[1 : len(part)-1]
    }
    return parts
}

测试它:

s := `['one', 'two', 'three']`
fmt.Printf("%q\n", split(s))
s = `[]`
fmt.Printf("%q\n", split(s))
s = `['o,ne', 't,w,o', 't,,hree']`
fmt.Printf("%q\n", split(s))

输出(在Go Playground上试试):

["one" "two" "three"]
[]
["o,ne" "t,w,o" "t,,hree"]

使用这个split() 函数,处理过程可能如下所示:

for _, line := range lines {
    data := CsvLine{
        Id:     line[0],
        Array1: split(line[1]),
        Array2: split(line[2]),
    }
    fmt.Printf("%+v\n", data)
}

这个输出(在Go Playground上试试):

{Id:594385903dss Array1:[fhjdsk dfjdskl fkdsjgooiertio] Array2:[jflkdsjfl fkjdlsfjdslkfjldks]}
{Id:87764385903dss Array1:[cxxc wqeewr opi iy qw] Array2:[cvbvc gf mnb ewr]}

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 2022-01-27
    • 1970-01-01
    • 2014-05-04
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    相关资源
    最近更新 更多