如何在Java中解析形式的csv文件

时间:2018-10-20 18:52:49

标签: java regex java.util.scanner

我正在尝试使用带定界符的扫描仪来解析格式相当特殊的文件,但是我对regex还是比较陌生的。格式:

“ 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周围的引号,这不是我想要的。

然后,我尝试使用以下定界符:

String delimiter = " "," ";

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

在我得到答案后对此进行了编辑,但是有什么方法可以通过使用“,”作为分隔符来实现我在第二个分隔符中想要的方式?

2 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分:0)

如果您只想使用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循环,通常这将是您想要该数据的最佳方式。

如果您想理解,则需要用其他信息更好地表达您的问题,以使您清楚自己的想法和原因,因为大多数帖子没有多大意义。