我有一个以逗号分隔的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);
}
如何转义带引号的令牌中的中间双引号?
答案 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所说,除非这是家庭作业,否则请使用图书馆!