首页 > 解决方案 > 没有正则表达式的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)

有没有我想念的明显方法来做到这一点?

标签: stringscalacsvparsing

解决方案


""""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 数据有一个单引号或任何奇数个引号,则结果可能不正确。


推荐阅读