【发布时间】:2016-07-04 12:34:17
【问题描述】:
在我的程序中,我得到了一个巨大的 csv String,我需要将其解析成一个数据表。数据是这样的:
["Email Address","First Name","Last Name","Phone #","Notes","Group"]
["email@email.com","First","Last","555-555-5555","Note",5]
["email2@email.com","First2","Last2","555-555-5555",null,3]
(要在这个上做一个MVCE,你可以用这个:)
String text = "[\"Email Address\",\"First Name\",\"Last Name\",\"Phone #\",\"Notes\",\"Group\"]\n" +
"[\"email@email.com\",\"First\",\"Last\",\"555-555-5555\",\"Note\",5]\n" +
"[\"email2@email.com\",\"First2\",\"Last2\",\"555-555-5555\",null,3]";
第一行是表头,后面的行是值。每行都包含在[ 和] 中,并且值以逗号分隔。
我需要:
- 分隔行
- 分隔每个值
对于#1,我认为这种方法很好:
Pattern eachLinePattern = Pattern.compile("\\[.*\\][\r\n]+");
Matcher matcher = eachLinePattern.matcher(text);
while (matcher.find()) {
String line = matcher.group().trim();
}
此正则表达式将捕获 [ 和 ] 之间的所有内容 (.*),后跟 \n 或 \r,这足以捕获所有行(这听起来像一个声明,但这是一个问题。我是否错过了这方面的潜在陷阱?)
对于#2,这是我遇到困难的地方。有些项目是字符串(""),有些不是(null、#s 等)。
我的第一个想法是使用逗号作为分隔符来创建.split():
Pattern eachLinePattern = Pattern.compile("\\[.*\\][\r\n]+");
Matcher matcher = eachLinePattern.matcher(text);
while (matcher.find()) {
String line = matcher.group().trim();
String[] eachItem = line.split(",");
for(String item : eachItem)
System.out.println(item);
}
但是,这也有明显的副作用,即在数据中捕获逗号。那么,如何确保数据中的逗号不会被捕获为错误的分隔符?
【问题讨论】:
-
不确定如果您的值分隔符也可能在值本身中找到,您可以做什么。也许尝试使用
","作为分隔符并从第一个元素中删除开头"并从最后一个元素中删除"- 只是一个想法 - update 仍然不确定如何处理null 值,但这可能是一个预处理步骤(即用空字符串替换 null) -
@ochi,我无法控制 CSV 格式。 :/ 要么解析它,要么死。
-
知道了。所以,在你之前
.split()用""替换 null (假设 null 是在这种情况下插入的单词)或在两个连续的逗号内插入一个空字符串......等等。 -
@ochi,虽然没有解决数字的问题。数据集中的非字符串值不仅仅是
nulls。 -
true... 数据集是否始终采用相同的格式?非字符串值总是“行”的最后一个元素吗? - 一些标准行分隔符失败,您可能需要做出一些假设