Действительно быстрая Java-функция для разделения строк без влияния на строки в кавычках? - PullRequest
0 голосов
/ 10 июля 2011

Мне нужна очень быстрая функция разбиения строк, которая разбивает строку через запятую, не разбивая строки, заключенные в двойные кавычки и содержащие запятые. Есть ли функция, которая делает это? Если это лучше всего обрабатывается регулярным выражением, пожалуйста, укажите необходимый шаблон и, если применимо, скажите мне любые советы по оптимизации скорости, о которых я должен знать. Например, если есть способ вызвать регулярное выражение таким образом, чтобы не требовалось каждый раз пересматривать шаблон регулярного выражения и т. Д. Эта функция будет вызываться тысячи раз за короткий период времени.

Обратите внимание, я видел сообщения о регулярном выражении на SO, как этот:

Регулярное выражение для разделения на запятую, за исключением случаев, когда оно заключено в кавычки

Но это были C # и другие языки, а не Java. Кроме того, если есть метод нерегулярных выражений, который быстрее, я бы хотел узнать об этом, как я указал выше.

- Рошлер

Ответы [ 4 ]

6 голосов
/ 10 июля 2011

Похоже, вы пытаетесь проанализировать строки / файлы в формате CSV?

Если это так, возможно, вам не нужно писать код самостоятельно. Извлечь библиотеку Apache Commons для анализа CSV:

http://commons.apache.org/sandbox/csv/

2 голосов
/ 10 июля 2011

В основном вы можете оторвать код C # из связанного вопроса, но вам нужно отменить его итератор, заменив yield return, скажем, добавив в список:

public static List<String> SplitCSV(String csvString)
    StringBuilder sb = new StringBuilder();
    boolean quoted = false;

    List<String> list = new ArrayList<String>();

    for(char c : csvString.toCharArray()) {
        if (quoted) {
            if (c == '"')
                quoted = false;
            else
                sb.append(c);
        } else {
            if (c == '"') {
                quoted = true;
            } else if (c == ',') {
                list.add(sb.toString());
                sb = new StringBuilder();
            } else {
                sb.append(c);
            }
        }
    }

    if (quoted)
        throw new IllegalArgumentException("csvString: Unterminated quotation mark.");

    list.add(sb.toString());
    return list;
}

Обратите внимание, что это, конечно, не касается экранированных кавычек в строках в кавычках ...

1 голос
/ 10 июля 2011

Я думаю, что наиболее популярными библиотеками для Java, которые делают это естественно, являются supercsv и opencsv . Вы ищете небиблиотечное решение?

0 голосов
/ 18 июля 2012

В библиотеке commons-lang есть также StrTokenizer:

StrTokenizer tokenizer = StrTokenizer.getCSVInstance();
tokenizer.reset(input);
String tokens[] = tokenizer.getTokenArray();

Существует также метод для получения токенов в виде списка, и он реализует функции Iterator / ListIterator, чтобы вы могли использовать его в стиле итератора while loop.

Вы также можете продолжать вызывать метод «reset», чтобы очистить экземпляр и проанализировать новые входные данные.

Следует отметить, что слова OpenCSV с экземплярами Reader будут разбираться на несколько строк. Этот класс работает со строками или массивами символов и анализирует только одну запись. Он имеет некоторые накладные расходы памяти в том, что весь анализ выполняется заранее, когда вы запрашиваете первый токен.

Это, однако, более настраиваемый, чем OpenCSV.

РАСКРЫТИЕ ИНФОРМАЦИИ: Я внес оригинальную версию этого класса в библиотеку.

...