2 回答
TA贡献1797条经验 获得超4个赞
您的输入格式不是有效的 CSV 格式。根据 Wikipedia Comma-separated values page,如果完全使用引号,则必须引用字段中的文字引号字符。
这意味着任何现有的通用 CSV 解析器库都不太可能处理同一文件中的两种类型的行。
为了说明这个问题有多深,请考虑:
130,TEXT 1" 67 SERIES, TEXT 2",4,1,998,.010,9,-,7,130
这可能意味着:
一个字段包含
TEXT 1" 67 SERIES, TEXT 2"
一个包含
TEXT 1 67 SERIES, TEXT 2
, 或两个字段
TEXT 1" 67 SERIES
和TEXT 2"
。
消除歧义的唯一方法是编写一些自定义逻辑以对其进行分类......基于您自己的业务规则。
我不认为你可以用split
和正则表达式来做到这一点。您需要编写一个适当的自定义解析器。
但在这种情况下,我认为您有权反对创建此 CSV 数据的任何人/任何人。他们应该遵守规则。我很想实现我的系统,通过现成的语法检查器提供 CSV 文件,并自动拒绝任何未通过验证的文件。
您可以自动修复报价中的错误吗?我认为不是……在一般情况下。如前所述,无法判断格式错误的 CSV 中的双引号是否应该是文字。它需要人类智能和领域知识来理解数据的含义。
TA贡献1998条经验 获得超6个赞
不知道如何(如果有的话)使用单个正则表达式来完成。但这是一种蛮力方法,它计算字符串中引号的数量并从那里开始。
public static void main(String[] args) {
System.out.println("---Type 1---");
for (String s : split("130,TEXT 1\" 67 SERIES ,400,4,1,998,.010,9,-,7,130")) {
System.out.println(s);
}
System.out.println("\n---Type 2---");
for (String s : split("130,\"TEXT, SAMPLE TEXT\",400,4,1,998,.010,9,-,7,130")) {
System.out.println(s);
}
}
private static List<String> split(String str) {
List<String> tokens = new ArrayList<>();
if (str.split("\"").length > 2) {
int firstQuoteIndex = str.indexOf("\"");
int secondQuoteIndex = str.indexOf("\"", firstQuoteIndex + 1);
tokens.add(str.substring(0, firstQuoteIndex - 1));
tokens.add(str.substring(firstQuoteIndex + 1, secondQuoteIndex));
tokens.addAll(Arrays.asList(str.substring(secondQuoteIndex + 2).split(",")));
} else {
tokens.addAll(Arrays.asList(str.split(",")));
}
return tokens;
}
输出
---Type 1---
130
TEXT 1" 67 SERIES
400
4
1
998
.010
9
-
7
130
---Type 2---
130
TEXT, SAMPLE TEXT
400
4
1
998
.010
9
-
7
130
添加回答
举报