簡體   English   中英

如何用逗號將逗號分隔的行(CSV)解析為某些項目?

[英]How to parse a comma separated line (CSV) with some items in quotation marks?

我正在嘗試使用以下方式解析逗號分隔的字符串:

val array = input.split(",")

然后,我注意到一些輸入行在引號內帶有“,”:

data0, "data1", data2, data3, "data4-1, data4-2, data4-3", data5

*請注意,數據不是很干凈,因此有些字段用引號引起來,而有些則不是


如何將這樣的行拆分為:

array(0) = data0
array(1) = data1
array(2) = data2
array(3) = data3
array(4) = data4-1, data4-2, data4-3
array(5) = data5

根據我的評論:

由於CSV文件圍繞引號,引號值中包含的逗號和引號的行為,因此解析CSV文件可能非常棘手。 我建議引入一個庫,該庫可以很好地處理所有極端情況。

您可以考慮的選項包括scala-csvtraversable-csv 或使用像opencsv這樣的Java庫。

否則,如果您不想或不能使用庫,則可以查看此SO答案此SO答案,以了解其他人如何處理自己的CSV解析器。

我建議使用CSV庫解析CSV數據-格式混亂且難以正確處理。

我建議使用kantan.csv ,主要是因為我是作者,但也因為它比將CSV流轉換為字符串數組的列表能讓您更進一步。 以以下輸入為例:

1,Foo,2.0
2,Bar,false

使用kantan.csv,您可以編寫:

import kantan.csv.ops._

new File("path/to/csv").asUnsafeCsvRows[(Int, String, Either[Float, Boolean])](',', false)

在結果上調用toList將產生:

List((1,Foo,Left(2.0)), (2,Bar,Right(false)))

請注意,最后一列是浮點型還是布爾型,但這是在迭代器的每個元素的類型中捕獲的。

以下是我解析CSV行的解決方案:

String[] res = row.split(";");
for (int i = 0; i < res.length; i++) {
    res[i] = deQuotes(res[i]);
}
return res;

用REGEXP刪除引號:

static final Pattern PATTERN_DE_QUOTES = Pattern.compile("(?i)^\\\"(.*)\\\"$");

static String deQuotes(String s) {
    Matcher matcher;
    if ((matcher = PATTERN_DE_QUOTES.matcher(s)).find()) {
        return matcher.group(1).replaceAll("\"\"", "\"");
    }
    return s;
}

希望對您有幫助。

實際上,您可以使用正則表達式來拆分該行。

val s = """data0, "data1", data2, data3, "data4-1, data4-2, data4-3", data5"""

"""((".*?")|('.*?')|[^"',]+)+""".r.findAllIn(s).foreach(println)

順便說一句 任何可以解析csv文件的庫也可以解析單個csv行。 只需將字符串包裝到StringReader中即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM