標籤:

Scala數據分析 Step:1.1=>添加解析csv功能

這個就不多說了...

我現在總結的csv數據存放規律如下:

0. 空格如果不在單元格(佔一行一列)中,不佔位。n1. 由分隔符(默認為,)分割列,由換行符分割行。n2. 當一個單元格包含分割符時,需要用雙引號 "" 把整體包裹起來。n3. 在有雙引號包裹的情況下,遭遇如下的正則匹配時完成一個單元格的解析。n (?<!")[ ]*,n4. 在有雙引號包裹的情況下,單元格中出現任意複數n個雙引號,解析為n-1個雙引號。n

感覺語言表達parse規律還挺不好說的,但我相信大家觀察一下csv文件源就能懂的~

然後解析一行的思路如下:

(xlsx解析模塊提供的介面也改成 read 方法了, unify最好了)

//解析csv的代碼結構如下:nobject csv{nn def read(path:String,sep:Char=,){nn def parse(row:String):ArrayBuffer[Any]{ //解析一行nn def dealWithQuote(str:String):String // 處理雙引號nn def getSplitIndexOf(str:String):(Int,String) // 處理單元格分割位置nn def halfSplit(str:String):(String,String) //將一行分為parsed 和 unparsednn def Go(str:String,res:ArrayBuffer[Any]=ArrayBuffer()):ArrayBuffer[Any]n // 執行處理一行的任務。nn }n }n}n

應該看一下go函數就懂了。

(我想知道我用遞歸的話,每次ArrayBuffer是不是重新生成的?... 如果是的話,我就把res改成read函數底下的變數。

@tailrecn def Go(str: String, res: ArrayBuffer[Any] = ArrayBuffer()): ArrayBuffer[Any] = {n if (str == "") resn else {n val (parsed, unparsed) = halfSplit(str)n Go(unparsed, res += parsed)n }n }n Go(row)n }n

總之Scala舒服。


推薦閱讀:

如何用谷歌日曆(google calendar)導入csv方式實現艾賓浩斯遺忘曲線複習?

TAG:Scala | csv |