【问题标题】:How to parse a form of csv file in java如何在java中解析一种形式的csv文件
【发布时间】:2018-10-20 18:52:49
【问题描述】:

我正在尝试通过使用带有分隔符的扫描仪来解析一个相当特殊格式的文件,但我对正则表达式相当陌生。格式:

"MARY","PATRICIA","LINDA","BARBARA","ELIZABETH","JENNIFER",...

目前,我正在使用以下分隔符和代码:

static void readNames(String[] names) {

    try {
        Scanner sc = new Scanner(new File("names.txt")).useDelimiter(",");
        int count = 0;

        while(sc.hasNext()) {

            names[count] = sc.next();
            count ++;


        }
    } catch (FileNotFoundException e) {

        e.printStackTrace();
    }

} 

但是,这给了我在字符串周围的引号,这不是我想要的。

然后,我尝试了以下分隔符:

String delimiter = " "," ";

由于引号的数量,我很快意识到它不能被识别为字符串。

这是在我得到答案后编辑的,但是有什么方法可以按照我在第二个分隔符中的意图,使用“,”作为分隔符吗?

【问题讨论】:

  • 你有没有尝试过?你到底卡在哪里了?
  • 请在写一些code 时写一个attempt。如果您遇到困难,请做一些research 并提供您发现的详细信息以及为什么它不能解决您的问题。有关详细信息,请参阅How to Ask a Good Question 页面。
  • 感谢您提供有关如何在未来提出问题的信息。非常感谢!
  • 将来不会。如果你认真地提出真正的问题,你应该改进这个问题。否则你只会吸引反对票和关闭票,这是从这里开始的糟糕方式。老实说,如果您认为您无法改进此问题,请考虑将其删除。
  • 再次抱歉,StackOverflow 的新手。 @GhostCat,我已根据您的建议编辑了问题。考虑再看一遍,谢谢!

标签: java regex java.util.scanner


【解决方案1】:

根据您帖子中提供的数据,我认为您可以使用这种模式“,|”

以下是你可以编写的代码,

public static void main(String[] args) throws Exception {
    Scanner sc = new Scanner(new FileInputStream("filename.txt"));
    sc.useDelimiter(Pattern.compile("\",\"|\""));

    while(sc.hasNext()) {
        System.out.println(sc.next());
    }
    sc.close();
}

【讨论】:

    【解决方案2】:

    如果你只是想要一个 java 编写的有用的 csv 解析器。最近写了一篇不错的:

    public static Iterable<String[]> parseCSV(final InputStream stream) throws IOException {
        return new Iterable<String[]>() {
            @Override
            public Iterator<String[]> iterator() {
                return new Iterator<String[]>() {
                    static final int UNCALCULATED = 0;
                    static final int READY = 1;
                    static final int FINISHED = 2;
                    int state = UNCALCULATED;
                    ArrayList<String> value_list = new ArrayList<>();
                    StringBuilder sb = new StringBuilder();
                    String[] return_value;
    
                    public void end() {
                        end_part();
                        return_value = new String[value_list.size()];
                        value_list.toArray(return_value);
                        value_list.clear();
                    }
    
                    public void end_part() {
                        value_list.add(sb.toString());
                        sb.setLength(0);
                    }
    
                    public void append(int ch) {
                        sb.append((char) ch);
                    }
    
                    public void calculate() throws IOException {
                        boolean inquote = false;
                        while (true) {
                            int ch = stream.read();
                            switch (ch) {
                                default: //regular character.
                                    append(ch);
                                    break;
                                case -1: //read has reached the end.
                                    if ((sb.length() == 0) && (value_list.isEmpty())) {
                                        state = FINISHED;
                                    } else {
                                        end();
                                        state = READY;
                                    }
                                    return;
                                case '\r':
                                case '\n': //end of line.
                                    if (inquote) {
                                        append(ch);
                                    } else {
                                        end();
                                        state = READY;
                                        return;
                                    }
                                    break;
                                case ',': //comma
                                    if (inquote) {
                                        append(ch);
                                    } else {
                                        end_part();
                                        break;
                                    }
                                    break;
                                case '"': //quote.
                                    inquote = !inquote;
                                    break;
                            }
                        }
                    }
    
                    @Override
                    public boolean hasNext() {
                        if (state == UNCALCULATED) {
                            try {
                                calculate();
                            } catch (IOException ex) {
                            }
                        }
                        return state == READY;
                    }
    
                    @Override
                    public String[] next() {
                        if (state == UNCALCULATED) {
                            try {
                                calculate();
                            } catch (IOException ex) {
                            }
                        }
                        state = UNCALCULATED;
                        return return_value;
                    }
                };
            }
        };
    }
    

    您通常会非常有帮助地处理这个问题,例如:

    for (String[] csv : parseCSV(stream)) {
        //<deal with parsed csv data>
    }
    

    通常它会将 csv 流解析器包装在一个可迭代对象中,以便您可以使用特殊的 java for 循环。所以你给它一个流,它会给你一个字符串数组的for循环,这通常是你想要这些数据的最佳方式。

    如果您更想理解,则需要用附加信息更好地表达您的问题,明确您认为您需要什么以及为什么需要,因为您的大部分帖子没有多大意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 2014-03-30
      • 1970-01-01
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多