我有一个逗号分隔的CSV文件包含纳斯达克符号。我使用Scanner读取文件
s = new Scanner(new File("C:\\nasdaq_companylist.csv")).useDelimiter("\\s*,\\s*");
我在第二个字段上遇到异常。问题是该字段与文件中的其他字段一样也包含逗号,例如" 1-800 FLOWERS.COM,Inc。" :
FLWS,"1-800 FLOWERS.COM, Inc.",2.8,76022800,n/a,1999,Consumer Services,Other Specialty Stores,http://www.nasdaq.com/symbol/flws
如何避免这个问题? 我的代码是:
List<Stock> theList = new ArrayList<Stock>();
StringBuilder sb = new StringBuilder();
//get the title
String title = s.nextLine();
System.out.println("title: "+title);
while (s.hasNext())
{
String symbol = s.next();
String name = s.next();
double lastSale = s.nextDouble();
long marketCap = s.nextLong();
String adr =s.next();
String ipoYear=s.next();
String sector=s.next();
String industry = s.next();
String summaryQuote = s.next();
theList.add(newStock(symbol,lastSale));}
由于
答案 0 :(得分:2)
除非这是作业,否则你不应该自己解析CSV。使用现有库之一。例如,这一个:http://commons.apache.org/sandbox/csv/
或google“java csv parser”并选择其他。
但是如果你想自己实现逻辑,你应该使用正则表达式的负前瞻功能(参见http://download.oracle.com/javase/1,5.0/docs/api/java/util/regex/Pattern.html)
答案 1 :(得分:1)
您最安全的选择是使用csv解析库。你的逗号用引号括起来。您需要实现逻辑来查找引用的逗号。但是,您还需要计划其他情况,例如报价中的引用,转义序列等。更好地使用一些即用型和经过测试的解决方案。使用谷歌,你会发现一些。 CSV文件可能很难自行使用。
答案 2 :(得分:1)
正如其他人正确指出的那样,滚动自己的csv解析器并不是一个好主意,因为它通常会在系统中留下巨大的安全漏洞。
那就是说,我使用这个正则表达式:
"((?:\"[^\"]*?\")*|[^\"][^,]*?)([,]|$)"
通过格式良好的csv数据做得很好。您需要使用Pattern
和Matcher
。
这就是它的作用:
/*
( - Field Group
(?: - Non-capturing (because the outer group will do the capturing) consume of quoted strings
\" - Start with a quote
[^\"]*? - Non-greedy match on anything that is not a quote
\" - End with a quote
)* - And repeat
| - Or
[^\"] - Not starting with a quote
[^,]*? - Non-greedy match on anything that is not a comma
) - End field group
( - Separator group
[,]|$ - Comma separator or end of line
) - End separator group
*/
请注意,它将数据解析为两个组,即字段和分隔符。它还在字段中留下引号字符,您可能希望删除它们并将“”替换为“etc。
答案 3 :(得分:0)
我希望您可以从正则表达式中删除\ \ s *。然后有:
while (s.hasNext() {
String symbol = s.next();
if (symbol.startsWith("\"")) {
while ((symbol.endsWith("\"") || symbol.length() == 1) && s.hasNext()) {
symbol += "," + s.next();
}
}
...