Как разобрать форму файла CSV в Java - PullRequest
0 голосов
/ 20 октября 2018

Я пытаюсь проанализировать файл специального формата, используя сканер с разделителем, но я довольно плохо знаком с регулярным выражением.Формат:

"МЭРИ", "ПАТРИЦИЯ", "ЛИНДА", "БАРБАРА", "ЭЛИЗАБЕТ", "ДЖЕННИФЕР", ...

В настоящее время я использую этот разделитель икод ниже:

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 = " "," ";

То, что я быстро понял, не распознается как строка из-за количества кавычек.

Это редактируется после того, как я получил свой ответ, но есть ли способ сделать это так, как я предполагал во втором разделителе, используя "," в качестве разделителя?

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Если вы просто хотите, чтобы 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 для массивов строк, который, как правило, будет наилучшим способом получения этих данных.

Если вы предпочитаете понимание, вы 'Вам нужно будет лучше сформулировать свой вопрос с дополнительной информацией, которая прояснит, что, по вашему мнению, вам нужно и почему, потому что большая часть вашего поста не имеет особого смысла.

0 голосов
/ 20 октября 2018

Основываясь на данных, приведенных в вашем посте, я думаю, что вы можете использовать этот шаблон "," | "

Ниже приведен тип кода, который вы можете написать,

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