猿问

Go 中的 CSV 解析器由于尾随空格而中断

我们正在尝试使用 Go 的 encoding/csv 包解析 csv 文件。这个特殊的 csv 有点特殊,每一行都有一个尾随空格。当尝试使用带引号的字段解码此 csv 时,包会中断,因为它需要换行符、分隔符或引号。尾随空格不是预期的。


你会如何处理这个案子?您知道我们可以使用的另一个解析器吗?


编辑:


f,err := os.Open("file.go")

// err etc..

csvr := csv.NewReader(f)

csvr.Comma = csvDelimiter

for {

   rowAsSlice, err := csvr.Read()

   // Handle row and errors etc.

}

编辑 2:CSV 示例,注意尾随空格!


"RECORD_TYPE","COMPANY_SHORTNAME" 

"HDR","COMPANY_EXAMPLE" 


慕婉清6462132
浏览 132回答 1
1回答

杨__羊羊

一种可能的解决方案是将源文件阅读器包装在自定义阅读器中,该阅读器的Read(...)方法会静默地从底层阅读器实际读取的内容中删除尾随空格。可以csv.Reader直接使用该类型。例如:type TrimReader struct{ io.Reader }var trailingws = regexp.MustCompile(` +\r?\n`)func (tr TrimReader) Read(bs []byte) (int, error) {  // Perform the requested read on the given reader.  n, err := tr.Reader.Read(bs)  if err != nil {    return n, err  }  // Remove trailing whitespace from each line.  lines := string(bs[:n])  trimmed := []byte(trailingws.ReplaceAllString(lines, "\n"))  copy(bs, trimmed)  return len(trimmed), nil}func main() {  file, err := file.Open("myfile.csv")  // TODO: handle err...  csvr := csv.NewReader(TrimReader{file})  for {    record, err := csvr.Read()    if err == io.EOF {      break    }    fmt.Printf("LINE: record=%#v, err=%v\n", record, err)  }  // LINE: record=[]string{"RECORD_TYPE", "COMPANY_SHORTNAME"}, err=<nil>  // LINE: record=[]string{"HDR", "COMPANY_EXAMPLE"}, err=<nil>}请注意,这里有一个微妙的错误,如果直到后续调用才读取行终止符,尾随空格仍然可以通过。您可以通过缓冲来解决问题,或者最好是简单地预处理这些 CSV 文件以在尝试解析它们之前删除尾随空格。
随时随地看视频慕课网APP

相关分类

Go
我要回答