- 将一个csv文件复制出来将后缀改变为txt,我们就得到了一个文件文件
- 打开这个txt文件,可以看到每一个字段之间都是用英文逗号隔开
正常的内容形似
20,C4,Pm,tem,tion,21,A4,E,H,"1,2,3,NA,aaa,bbbb,cccc,ddd,N/A,aaa,bbbb,cccc,ddd,tttttt
对于这种我们只需要进行简单的逗号分割就可以拿到每个字段的值
String input = "20,C4,Pm,tem,tion,21,A4,E,H,\"1,2,3,NA,aaa,bbbb,cccc,ddd,N/A,aaa,bbbb,cccc,ddd,tttttt";
String[] fields = input.split(",");
for (String field : fields) {
System.out.println(field);
}
带引号的文本
当我们打开文件如果看到,文本中有的字段是双引号括起来的,里面也同样用逗号隔开,上面的方法便不再适用了,文本内容如下
20,C4,Pm,tem,tion,21,A4,E,H,"1,2,3",NA,"aaa,bbbb,cccc,ddd",N/A,"aaa,bbbb,cccc,ddd",tttttt
这里我们可以看到 "1,2,3"
"aaa,bbbb,cccc,ddd"
"aaa,bbbb,cccc,ddd"
这三组都是被引号括起来的
此时采用
public class CSVReader {
public static void main(String[] args) {
String csvFile = "path/to/your/csv/file.csv";
String line = "";
String csvSplitBy = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)";
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
String[] data = line.split(csvSplitBy);
for (String datum : data) {
System.out.print(datum + " ");
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
解释如下:
这个正则表达式可以分为两部分:
- 逗号分隔符:
,
- 前瞻语法:
(?=([^\"]*\"[^\"]*\")*[^\"]*$)
前瞻语法是一种零宽度断言,它用于匹配一个位置,这个位置后面的文本符合某种模式。这个正则表达式中的前瞻语法表示:
(?=...)
:表示正向前瞻,即匹配后面的文本必须符合括号中的模式。([^\"]*\"[^\"]*\")*
:表示匹配任意数量的双引号内的文本,其中:
[^\"]*
:表示匹配任意数量的非双引号字符。\"[^\"]*\"
:表示匹配一对双引号内的任意数量的非双引号字符。(...)*
:表示匹配任意数量的前面的模式。
[^\"]*$
:表示匹配任意数量的非双引号字符,直到字符串末尾。
综合起来,这个正则表达式的意思是:匹配逗号,并且这个逗号后面的文本必须符合以下模式:在这个逗号后面,如果有偶数个双引号,则这个逗号是字段分隔符;如果有奇数个双引号,则这个逗号是双引号内的文本,不是字段分隔符。这个正则表达式的作用是避免将双引号内的逗号误认为是字段分隔符。