标记CSV行转义双引号

时间:2019-10-25 14:56:08

标签: java regex csv

我有一个以逗号分隔的CSV行:

1000102257,b,N,159999,3,4545656,4,,,,"6,125% NORDRHEIN-WESTF.LA.SCHA.R.239 21.12. "18"

包含逗号定界符(,)作为内容的标记被双引号引起来。

如您所见,最后一个标记是双引号之间的分隔符,但另一个双引号出现(“ 18”)破坏了标记化机制:

"6,125% NORDRHEIN-WESTF.LA.SCHA.R.239 21.12. "18"

这是我的代码,用于将标记分割成一行:

public static void main(String[] args) {
    final String cvsSplitterEscapingQuotes = ",(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)";
    String strLine = "1000102257,b,N,159999,3,4545656,4,,,,\"6,125% NORDRHEIN-WESTF.LA.SCHA.R.239 21.12. \"18\"";
    String[] tokens = strLine.split(cvsSplitterEscapingQuotes, -1);
}

如何转义带引号的令牌中的中间双引号?

3 个答案:

答案 0 :(得分:4)

不要自己解析CSV,请使用库。即使像CSV这样的简单格式也有细微差别:可以使用引号对字段进行转义或不使用转义,文件可以具有或不具有标题等等。除此之外,您还必须测试和维护您编写的代码。因此,编写更少的代码和重用库是很好的。

Java中有很多CSV的库:

恕我直言,前两个最受欢迎。

以下是Apache Commons CSV的示例:

query_params = [
        bigquery.ScalarQueryParameter("_date_", "STRING", "2019-10-24")
]
job_config = bigquery.QueryJobConfig()
job_config.query_parameters = query_params

#delete
sql = """
delete from `b` 
where _date_ = @_date_
"""
query_job = client.query(sql, job_config=job_config)
results = query_job.result()

# reset config
job_config = bigquery.QueryJobConfig()
job_config.query_parameters = query_params

#insert
sql = """
insert into `b` (col1,col2)
select col1, col2 from a
where a._date_ = @_date_
"""
query_job = client.query(sql, job_config=job_config)
results = query_job.result()

看这有多容易!它将与其他解析器类似。

答案 1 :(得分:0)

只需忽略不用逗号或换行符引起的双引号

答案 2 :(得分:0)

此未经转义的正则表达式已通过here测试:

(".*"|[^,"]+|(?<=,)(?=,))

用逗号分隔字符串,但不带引号。运作方式如下:

(                          // Start the match
 ".*"                      // Greedily match anything in quotes
     |[^,"]+               // Or, greedily match anything that isn't a comma or quote
            |(?<=,)(?=,)   // Or, look behind for a comma and ahead for a comma
                           //    (the empty match)
                        )  // End match.

当然,这不会与逗号分隔的字符串开头或结尾的空白字段匹配,但是您可以添加其他位:

|^(?=,)           // At the beginning, look forward for a comma
       |(?<=,)$   // Look back for a comma, and at the end

所以整个模式是:

(".*"|[^,"]+|(?<=,)(?=,))|^(?=,)|(?<=,)$

但是正如@madhead所说,除非这是家庭作业,否则请使用图书馆!