[英]Scala CSV parser removed spaces
我正在嘗試將以下行解析為數據數組:
"John,Doe","123 Main St","Brown Eyes"
我想要一個如下的數組data
:
data(0) = John,Doe
data(1) = 123 Main St
data(2) = Brown Eyes
我從網站使用以下CSV解析器:
import scala.util.parsing.combinator._
object CSV extends RegexParsers {
override protected val whiteSpace = """[ \t]""".r
def COMMA = ","
def DQUOTE = "\""
def DQUOTE2 = "\"\"" ^^ { case _ => "\"" }
def CR = "\r"
def LF = "\n"
def CRLF = "\r\n"
def TXT = "[^\",\r\n]".r
def file: Parser[List[List[String]]] = repsep(record, CRLF) <~ opt(CRLF)
def record: Parser[List[String]] = rep1sep(field, COMMA)
def field: Parser[String] = (escaped|nonescaped)
def escaped: Parser[String] = (DQUOTE~>((TXT|COMMA|CR|LF|DQUOTE2)*)<~DQUOTE) ^^ { case ls => ls.mkString("")}
def nonescaped: Parser[String] = (TXT*) ^^ { case ls => ls.mkString("") }
def parse(s: String) = parseAll(file, s) match {
case Success(res, _) => res
case _ => List[List[String]]()
}
}
然后修剪所有空間。 數據數組實際上看起來像:
data(0) = John,Doe
data(1) = 123MainSt
data(2) = BrownEyes
如何避免CSV解析器出現這種不必要的“刪除空格”? 謝謝!
您的代碼說要采用一系列轉義或不轉義的令牌,並在中間插入空格:
...* ^^ { case ls => ls.mkString("") }
根據RegexParsers
的文檔,
嘗試關閉skipWhitespace
:
override protected val skipWhitespace = false
手寫CSV解碼器而不是使用許多現有的,經過良好測試的解碼器有什么特殊的原因嗎? 如OpenCSV
或Jackson CSV module
。 使用現有的lib應該更簡單,並且在嘗試取消轉義引號,修剪(或不修剪)空格等時,您不會遇到各種問題。
Robert Starling給出了您問題的准確答案:將skipWhitespace
設置為false
。
我假設您真正想知道的問題“如何可靠地解析CSV?”的答案是“使用專用庫”。
您可以使用Java之一-opencsv,commons-csv,jackson-csv,univocity ...或Scala之一-產品集合,purecsv,kantan.csv ...
不要在沒有充分理由的情況下編寫自己的文件-我寫了表格,是因為我需要比當時更好的類型處理-如果這樣做,請不要使用Scala解析器組合器庫之一:它們將整個數據加載為解析之前在內存中的字符串,當數據開始增長時,它根本不會縮放。
如果您必須編寫自己的文件並想使用解析器組合器庫(因為,面對現實,這是一個有趣的問題,並且那些庫很酷),請考慮使用fastparse或將其parboiled,它們的質量都比標准Scala高一。
您可以在一行中完成此工作:
line.split((",(?=([^\"]*\"[^\"]*\")*[^\"]*$)")
正則表達式來自此處 ,然后將其應用於文件的所有行。 這只會將逗號分隔為兩個引號之外。
解析csv文件的代碼:
scala> scala.io.Source.fromFile("toto.csv").getLines.toList.map(_.split((",(?=([^\\"]*\\"[^\\"]*\\")*[^\\"]*$)"))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.