我对Scala完全不熟悉,并且正在尝试解析一个CSV文件,该文件具有回车符/新行/以及其他特殊字符,例如某些单元格中的逗号(即双引号内),例如:
"A","B","C\n,FF\n","D"\n
"Q","W","E","R\n\n"\n
"1","2\n","2","2,2\n"\n
我想将其加载到Scala中的列表类型列表中,如下所示:
List(List("A","B","C,FF","D"),List("Q","W","E","R"),List("1","2","2","2,2"))
有关如何做到的任何建议吗?
我在其他语言中找到了针对同一问题的一些解决方案。例如,这是Python中的一个很好的,我很清楚:Handling extra newlines (carriage returns) in csv files parsed with Python?
我的尝试:
val src2 = Source.fromFile("sourceFileName.csv")
val it =src2.getLines()
val data = for (i<-it) yield i.replace("\"","").split(",")
但看起来所有回车都被视为新线路。
答案 0 :(得分:2)
在我看来,如果实际的单元格包含换行符,那么在遍历getLines
时你需要保持一些状态。您可以使用foldLeft
或类似的运算符执行此操作。如果文件足够小,您还可以使用mkString
将整个文件作为字符串存储在内存中,然后对其进行操作。以下简化版本假定每个单元格都用引号括起来。例如:
val converted = Source.fromFile(sourceFileName).mkString.replaceAll("\n", "").replaceAll("\"\"", "\"\n\"")
首先,我们要删除所有新行。然后,真正的新行将在一行中显示为两个引号(因为否则会有一个逗号分隔引号),因此我们在引号之间添加新行。然后我们应该有一个标准化版本的文件,我们可以进行简单的操作:
converted.split("\n").map(_.split(",").map(_.replaceAll("\"", "")))
答案 1 :(得分:1)
最简单的方法是过滤空行并修剪额外的空格:
val src2 = Source.fromFile(sourceFileName)
val it = src2.getLines()
val data = for (i<-it if !i.trim.isEmpty) yield i.trim.replace("\"","").split(",")
答案 2 :(得分:0)
我找到了解决方案。它类似于Ben Reich的解决方案,但在双引号内处理任何其他特殊字符:
Source.fromFile(sourceFileName).mkString.split("\"\n\"").map(_.split("\",\""))