string - 没有正则表达式的Scala CSV解析
问题描述
我正在为 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 数据有一个单引号或任何奇数个引号,则结果可能不正确。