为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕婉清6462132 2023-04-04 17:17:12
我们正在尝试使用 Go 的 encoding/csv 包解析 csv 文件。这个特殊的 csv 有点特殊,每一行都有一个尾随空格。当尝试使用带引号的字段解码此 csv 时,包会中断,因为它需要换行符、分隔符或引号。尾随空格不是预期的。你会如何处理这个案子?您知道我们可以使用的另一个解析器吗?编辑:f,err := os.Open("file.go")// err etc..csvr := csv.NewReader(f)csvr.Comma = csvDelimiterfor {   rowAsSlice, err := csvr.Read()   // Handle row and errors etc.}编辑 2:CSV 示例,注意尾随空格!"RECORD_TYPE","COMPANY_SHORTNAME" "HDR","COMPANY_EXAMPLE" 
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

一种可能的解决方案是将源文件阅读器包装在自定义阅读器中,该阅读器的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 文件以在尝试解析它们之前删除尾随空格。


查看完整回答
反对 回复 2023-04-04
  • 1 回答
  • 0 关注
  • 131 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信