【问题标题】:How to deserialize json comma-separated strings from CSV file如何从 CSV 文件反序列化 json 逗号分隔的字符串
【发布时间】:2020-03-06 16:01:26
【问题描述】:

我有一个 mysql 转储 csv 文件,其中包含两列 json1 和 json2,这两列都是 JSON 对象字符串表示形式。因此 csv 行如下所示:

"{"field1":"value","field2":4}","{"field1":"value","field2":4}"

我需要反序列化这两个字符串,然后将 JSON 解组为 Go 值。我被困在第一步。我在使用 , 时遇到了问题,因为 JSON 字符串本身在其中包含 ,s,因此读者会在错误数量的字段中分断每一行,而不需要两个。

这是我的完整代码:

reader := csv.NewReader(csvFile)
reader.LazyQuotes = true //allows non-doubled quotes to appear in quoted fields

for {

    record, err := reader.Read()
    if err == io.EOF {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("json1: %s json2 %s\n", record[0], record[1])
}

我的尝试

我尝试将 csv 分隔符设置为 }","{,然后将相应的 }{ 附加到结果字符串,但是,除了容易出错之外,一些行还有 NULL json1或 json2。

观察

我正在使用 - golang 1.12.1

【问题讨论】:

  • 这既不是正确的 CSV 也不是 JSON。您可以使用字符串阅读器读取该行,使用第一个引号,然后使用解码器解析 JSON,然后使用 ",",然后使用解码器再次解析其余部分。
  • 这基本上是不可能的。要么指定文件的格式,要么你必须为它编写一个解析器(你不能使用 encoding/{csv,json} 除非它实际上是 is CSV 和 JSON 或格式未指定,您需要使用似乎有效的启发式方法。有时更改上游更容易。

标签: json csv go


【解决方案1】:

我只会使用strings.Split() 拆分}","{(如果您确定这将始终有效),然后按照您的说法解组 JSON 字符串。你能让转储文件以某种方式分隔嵌套引号吗?

columns := strings.Split(`"{"field1":"value","field2":4}","{"field1":"value","field2":5}"`, `}","{`)
for i, s := range columns {
    if i == 0 {
        s = s[1:]  // remove leading quote
    }
    if i == len(columns) - 1 {
        s = s[:len(s)-1] // remove trailing quote
    }
    if i > 0 {
        s = "{" + s
    }
    if i < len(columns) - 1 {
        s += "}"
    }
    // unmarshal JSON ...
}

这有点麻烦,但即使某些字段为 NULL 也应该可以工作。

【讨论】:

  • }","{ 上拆分将不起作用,因为有时一个 json 或另一个具有 NULL 值。我不确定是否可以将嵌套引号分隔我会发现,如果可能的话你会建议什么?
  • 感谢您的回答,我最终实现了与您的建议非常相似的东西。由于我不需要处理缺少其中一个 JSON 的行,因此我将 Split 返回的字段长度作为参考,如果它不同于 2,我将跳过该行。对这种方法并不完全满意,但由于我无法更改输入文件,所以现在就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多