go encoding / csv中引用字符串的奇怪CSV结果

时间:2013-12-08 21:02:37

标签: string csv escaping go

我有一些代码让我整个周末都很忙。

package main

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

func main() {
    f, err := os.Create("./test.csv")
    if err != nil {
        log.Fatal("Error: %s", err)
    }
    defer f.Close()

    w := csv.NewWriter(f)
    var record []string
    record = append(record, "Unquoted string")
    s := "Cr@zy text with , and \\ and \" etc"
    record = append(record, s)
    fmt.Println(record)
    w.Write(record)

    record = make([]string, 0)
    record = append(record, "Quoted string")
    s = fmt.Sprintf("%q", s)
    record = append(record, s)
    fmt.Println(record)
    w.Write(record)

    w.Flush()
}

运行时打印出来:

[Unquoted string Cr@zy text with , and \ and " etc]
[Quoted string "Cr@zy text with , and \\ and \" etc"]

第二个引用的文字正是我希望在CSV中看到的,但我得到了这个:

Unquoted string,"Cr@zy text with , and \ and "" etc"
Quoted string,"""Cr@zy text with , and \\ and \"" etc"""

这些额外报价来自哪里,如何避免它们? 我尝试了很多东西,包括使用strings.Quote和一些这样的但我似乎无法找到一个完美的解决方案。请帮帮忙?

3 个答案:

答案 0 :(得分:5)

这是将数据存储为CSV的标准的一部分。 出于解析原因,需要对双引号字符进行转义。

字段中的(双)引号字符必须由两个(双)引号字符表示。

来自:http://en.wikipedia.org/wiki/Comma-separated_values

你真的不必担心,因为CSV阅读器取消了双引号。

实施例

package main

import (
    "encoding/csv"
    "fmt"
    "os"
)
func checkError(e error){
    if e != nil {
        panic(e)
    }
}
func writeCSV(){
    fmt.Println("Writing csv")
    f, err := os.Create("./test.csv")
    checkError(err)
    defer f.Close()

    w := csv.NewWriter(f)
    s := "Cr@zy text with , and \\ and \" etc"
    record := []string{ 
      "Unquoted string",
      s,
    }
    fmt.Println(record)
    w.Write(record)

    record = []string{ 
      "Quoted string",
      fmt.Sprintf("%q",s),
    }
    fmt.Println(record)
    w.Write(record)
    w.Flush()
}
func readCSV(){
    fmt.Println("Reading csv")
    file, err := os.Open("./test.csv")
    defer file.Close();
    cr := csv.NewReader(file)
    records, err := cr.ReadAll()
    checkError(err)
    for _, record := range records {
        fmt.Println(record)
    }
}
func main() {
   writeCSV()
   readCSV()
}

输出

Writing csv
[Unquoted string Cr@zy text with , and \ and " etc]
[Quoted string "Cr@zy text with , and \\ and \" etc"]
Reading csv
[Unquoted string Cr@zy text with , and \ and " etc]
[Quoted string "Cr@zy text with , and \\ and \" etc"]

这是写函数的代码。 func (w *Writer) Write(record []string) (err error)

答案 1 :(得分:3)

我的csv文件包含双引号字符串,如:

  

文本; // * [@类= “价格”] /跨度;文本

并且csv Reader生成错误以读取csv文件。 有用的是:

reader := csv.NewReader(file)
reader.LazyQuotes = true

答案 2 :(得分:-1)

s变量的值不是你想象的那样。 http://play.golang.org/p/vAEYkINWnm