在文本字段中使用java - 逗号分隔符读取csv文件

时间:2011-11-07 09:42:36

标签: java csv

我有一个逗号分隔的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));} 

由于

4 个答案:

答案 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数据做得很好。您需要使用PatternMatcher

这就是它的作用:

/*
 ( - 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();
        }
    }
...