我正在为一个scala项目编写一个小型CSV解析器。项目规定不允许使用正则表达式或非官方的外部库。
我有它的大部分工作,但是有一个情况是给我麻烦,那就是当CSV单元格内的数据包含一个逗号。
我正在解析存储在CSV中的数据集。解析函数接受字符串数组作为其唯一参数这个数组表示从CSV中获取一行并调用split(",")
。存储在CSV中的数据的格式是这样的,如果数据中有逗号,那么整个数据单元格将被括在引号("")
中。问题是,当split(",")
被调用时,它在引用单元格的中间分裂,因为它不知道忽略逗号。我需要一种方法来忽略逗号,本质上是"修复"。参数数组
假设CSV中的一行在任何分割发生之前看起来是这样的。
"Hello, everyone", green, blue, 5, 3.2
在split(",")
之后,我们最终得到
|"hello|everyone"|green|blue|5|3.2| // (Array length 6)
在我需要的地方
|"hello, everyone"|green|blue|5|3.2| //( Array length 5)
是否有一个明显的方法来做到这一点,我错过了?
""""Hello, everyone",green,blue,5,3.2""" //raw CSV
.split(",") //split at all commas
.foldRight((List[String](), false)){ //recombine quoted strings
case (str,(lst, false)) => (str :: lst, str.count(_ == '"')%2 > 0)
case (str,(hd::tl,true)) => (s"$str,$hd"::tl, str.count(_ == '"')%2 < 1)
}._1
.mkString("|") //reformat just to demonstrate success
//res0: String = "Hello, everyone"|green|blue|5|3.2
注意:这里假设引号"
成对出现。如果原始CSV数据有一个引号,或者有奇数个引号,那么结果可能是不正确的。