Относительно манипуляции строк Java - PullRequest
2 голосов
/ 11 февраля 2010

У меня есть строка "MO""RET", которая сохраняется в массиве items[1] после команды split. После того, как он сохранен, я выполняю замену для всей строки, и она заменяет все двойные кавычки. Но я хочу, чтобы он хранился как MO"RET. Как мне это сделать. В файле csv, из которого я обрабатываю команду split, повторяются двойные кавычки в содержимом текстового поля (пример: это учетная запись ""large"" one "). Поэтому я хочу сохранить одну из двух кавычек в середине строка, если она повторяется, и игнорировать конечные кавычки, если они есть. Как я могу это сделать?

String items[] = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
items[1] has "MO""RET"
String recordType = items[1].replaceAll("\"","");

После этого recordType имеет MORET Я хочу, чтобы он имел MO"RET

Ответы [ 4 ]

6 голосов
/ 11 февраля 2010

Не используйте регулярные выражения для разделения строки CSV. Это напрашивается на неприятности;) Просто разбери его по буквам. Вот пример:

public static List<List<String>> parseCsv(InputStream input, char separator) throws IOException {
    BufferedReader reader = null;
    List<List<String>> csv = new ArrayList<List<String>>();
    try {
        reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
        for (String record; (record = reader.readLine()) != null;) {
            boolean quoted = false;
            StringBuilder fieldBuilder = new StringBuilder();
            List<String> fields = new ArrayList<String>();
            for (int i = 0; i < record.length(); i++) {
                char c = record.charAt(i);
                fieldBuilder.append(c);
                if (c == '"') {
                    quoted = !quoted;
                }
                if ((!quoted && c == separator) || i + 1 == record.length()) {
                    fields.add(fieldBuilder.toString().replaceAll(separator + "$", "")
                        .replaceAll("^\"|\"$", "").replace("\"\"", "\"").trim());
                    fieldBuilder = new StringBuilder();
                }
                if (c == separator && i + 1 == record.length()) {
                    fields.add("");
                }
            }
            csv.add(fields);
        }
    } finally {
        if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
    }
    return csv;
}

Да, здесь используется небольшое регулярное выражение, но оно удаляет только конечный разделитель и окружающие кавычки одного поля.

Однако вы также можете получить любую стороннюю Java CSV API .

1 голос
/ 11 февраля 2010

Как насчет:

String recordType = items[1].replaceAll( "\"\"", "\"" );
0 голосов
/ 11 февраля 2010

Здесь вы можете использовать регулярное выражение.

recordType = items[1].replaceAll( "\\B\"", "" ); 
recordType = recordType.replaceAll( "\"\\B", "" ); 

Первое утверждение заменяет кавычки в начале слова на пустой символ. Второе утверждение заменяет кавычки в конце слова на пустой символ.

0 голосов
/ 11 февраля 2010

Я предпочитаю использовать замену вместо replaceAll. replaceAll использует REGEX в качестве первого аргумента.

Требуется заменить две продолжающиеся цитаты одной цитатой

String recordType = items[1].replace( "\"\"", "\"" );

Чтобы увидеть разницу между заменой и заменой всех, выполните приведенный ниже код

recordType = items[1].replace( "$$", "$" );
recordType = items[1].replaceAll( "$$", "$" );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...