高手高高手请进:JAVA解析CSV文件

whut_lcy 2010-05-24 04:27:29
首先说明:本人已经用过正则,opencsv(apache的),javacsv2.0(商业的).... try过无数次,都无法搞定!!
请不要告诉我用上述办法,甚至String.split(",")。。。这样最原始的搞法,因为我都试过

其实我的需求就一样事情:如何处理csv数据中包含的逗号??如果不是这个原因我也不会发这个帖子了。。。

略略贴一贴正则的:

        String str = "7,,08020056,,C.3,-,P,SYMBIAN,\"\"NOKIA,SAMSUNG,Sony Erission\"\",9.0,NPS,\"\"N73,8250,N97,E61,E71,5320,8855,6210C,N95\"\",";
String regex = "\\G(?:^|,)(?:\"([^\"]*+(?:\"\"[^\"]*+)*+)\"|([^\",]*+))";
Matcher main = Pattern.compile(regex).matcher(str);
Matcher mquote = Pattern.compile("\"\"").matcher("");
while (main.find()) {
String field;
if (main.start(2) >= 0) {
field = main.group(2);
} else {
field = mquote.reset(main.group(1)).replaceAll("\"");
}
System.out.println("Field [" + field + "]");
}


正常情况下, str解析出来的东东应该是这样(数据用[]包含起来):
[7],[],[08020056],[],[C.3],[-],[P],[SYMBIAN],[NOKIA,SAMSUNG,SonyErission],[9.9],[NPS],[N73,8250,N97,E61,5320,8855,6210C,N95]


但上述正则输出的不是这个内容,而且opencsv,javacsv2输出的也都不符合我的要求。其实主要就是红色部分不符合。

特发帖求解!!!

...全文
912 点赞 收藏 22
写回复
22 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
天才冬冬 2012-03-27
10楼的regex改成
String regex = "((\"[^\"]*(\"{2})*[^\"]*\")*[^,]*)(,)";
就可以了。lz可以试一试
回复
grzrt 2011-11-26
没有解决呀 失望
回复
小呆 2010-09-16
学习下,不知结贴了 ,发帖还能得分不
回复
whut_lcy 2010-06-09
算了不等了,下班结贴。

3楼说的要规范CSV输出,这个不是我说了算。这个格式的CSV是另一个系统做的,与其推动其修改CSV,不如直接让它导出XLS。POI直接解析。

无论你什么样的CSV,只要告诉MS的EXCEL它的分隔符是什么,他都可以正确解析。纳了闷了。。。

另外,据说ms 的sql server可以直接用sql语句将xls文件导入数据库。其他数据库应该不支持吧?毕竟xls是ms 的东西

回复
whut_lcy 2010-06-09
10楼的输出还是不对

Field [7]
Field []
Field [08020056]
Field []
Field [C.3]
Field [-]
Field [P]
Field [SYMBIAN]
Field [NOKIA]
Field [SAMSUNG]
Field [Sony Erission]
Field [9.0]
Field [NPS]
Field [N73]
Field [8250]
Field [N97]
Field [E61]
Field [E71]
Field [5320]
Field [8855]
Field [6210C]
Field [N95]

N73,8250,N97,E61,E71,5320,8855,6210C,N95 没在一行上
回复
tiamay 2010-06-08
高深的技术哦 小弟受教育了
回复
hq1305018 2010-06-08

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Test20100607 {

/**
* @param args
*/
public static void main(String[] args) {
String str = "7,,08020056,,C.3,-,P,SYMBIAN,\"\"NOKIA,SAMSUNG,Sony Erission\"\",9.0,NPS,\"\"N73,8250,N97,E61,E71,5320,8855,6210C,N95\"\",";
String regex = "([^,]*)(,)";
Matcher main = Pattern.compile(regex).matcher(str);
while (main.find()) {
String field;
field = main.group(1).replaceAll("\"","");
System.out.println("Field [" + field + "]");
}

}

}

回复
truediego 2010-06-08
[Quote=引用 3 楼 dollyn 的回复:]
你应该修改你的源文件,修改成为符合标准CSV文件的格式:

Java code
CSV逗号分隔值文件
  规则
  0 开头是不留空,以行为单位。
  1 可含或不含列名,含列名则居文件第一行。
  2 一行数据不垮行,无空行。
  3 以半角符号,作分隔符,列为空也要表达其存在。
  4 列内容如存在半角逗号(即,)则用半角引号(即"")将该字段值包含起来。
  5 列内容如……
[/Quote]

这才是正道
回复
whut_lcy 2010-06-08
10楼 的代码没贴全
回复
不对吧

如果字段中含有逗号,那么这个字段用引号包起来,如果字段中含有引号,那就使用两个引号进行转义。

你示例的 CSV 中,有两个引号的,为什么没有看“应该”当中有引号啊?
回复
whut_lcy 2010-06-07
下班结贴
回复
whut_lcy 2010-06-07
[Quote=引用 6 楼 cooljia 的回复:]
像你这样的,是需求有问题,如果数据中有大量的逗号,干嘛还要用csv格式?
换成"|"或者tsv格式都可以,甚至xml格式
你这是自寻死路!
[/Quote]

犀利哥吗?言辞好犀利,嘎嘎。。。

帅哥,问题是这个CSV并非我生成的,而是其他系统导出的,是不是要推动别人去修改它的代码啊。。。CSV生成很容易,解析就难了,就像MD5.。。

不过该问题已经曲线解决了。如同楼上有人说的,另存为XLS + POI...

而且感觉该问题肯定有解,否则EXCEL怎么能正确打开CSV。。。

回复
whut_lcy 2010-06-07
[Quote=引用 11 楼 mybeautiful 的回复:]
引用 8 楼 whut_lcy 的回复:
不过该问题已经曲线解决了。如同楼上有人说的,另存为XLS + POI...

如果楼主是手工把cvs另存为xls,那问题似乎还是没有完美解决。
[/Quote]

是啊,明天验证下10楼的,如果解决,全额送分!
回复
Mybeautiful 2010-06-07
[Quote=引用 8 楼 whut_lcy 的回复:]
不过该问题已经曲线解决了。如同楼上有人说的,另存为XLS + POI...[/Quote]

如果楼主是手工把cvs另存为xls,那问题似乎还是没有完美解决。
回复
hq1305018 2010-06-07

String str = "7,,08020056,,C.3,-,P,SYMBIAN,\"\"NOKIA,SAMSUNG,Sony Erission\"\",9.0,NPS,\"\"N73,8250,N97,E61,E71,5320,8855,6210C,N95\"\",";
String regex = "([^,]*)(,)";
Matcher main = Pattern.compile(regex).matcher(str);
while (main.find()) {
String field;
field = main.group(1).replaceAll("\"","");
System.out.println("Field [" + field + "]");
}


Field [7]
Field []
Field [08020056]
Field []
Field [C.3]
Field [-]
Field [P]
Field [SYMBIAN]
Field [NOKIA]
Field [SAMSUNG]
Field [Sony Erission]
Field [9.0]
Field [NPS]
Field [N73]
Field [8250]
Field [N97]
Field [E61]
Field [E71]
Field [5320]
Field [8855]
Field [6210C]
Field [N95]
回复
ycnanevol 2010-06-05
我觉得可以不用csv格式的,直接xls格式保存数据
然后用POI来操作excel
回复
cooljia 2010-06-05
像你这样的,是需求有问题,如果数据中有大量的逗号,干嘛还要用csv格式?
换成"|"或者tsv格式都可以,甚至xml格式
你这是自寻死路!
回复
xtuxucj 2010-06-05
建议使用smooks这个插件。可以解析csv,xml,edi,flatfile等等。具体情况google一下吧。
回复
whut_lcy 2010-06-03
每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分
回复
霜之哀伤 2010-05-24
你应该修改你的源文件,修改成为符合标准CSV文件的格式:
CSV逗号分隔值文件
  规则
  0 开头是不留空,以行为单位。
  1 可含或不含列名,含列名则居文件第一行。
  2 一行数据不垮行,无空行。
  3 以半角符号,作分隔符,列为空也要表达其存在。
  4 列内容如存在半角逗号(即,)则用半角引号(即"")将该字段值包含起来。
  5 列内容如存在半角引号(即")则应替换成半角双引号("")转义。
  6 文件读写时引号,逗号操作规则互逆。
  7 内码格式不限,可为ASCII、Unicode或者其他。

然后用标准CSV库解析。

比如XML,<xxx="<>">没有那种解析引擎可以解析这样的东西
回复
加载更多回复
相关推荐
发帖
Java SE
创建于2007-09-28

6.1w+

社区成员

Java 2 Standard Edition
申请成为版主
帖子事件
创建了帖子
2010-05-24 04:27
社区公告
暂无公告