#java #regex #csv #separator
#java #регулярное выражение #csv #разделитель
Вопрос:
Я должен изменить программу. Эта программа создает файл csv со столбцами в базе данных, подобными этому :
csvBuilder.initCsvFile();
csvBuilder.createRow(headers.toArray(new String[headers.size()]));
while (resultSet.next()) {
String[] row = new String[resultSetColumnCount];
int columnIndex = 1;
while (columnIndex <= resultSetColumnCount) {
Object object = resultSet.getObject(columnIndex);
if (object == null) {
row[columnIndex - 1] = "";
} else {
row[columnIndex - 1] = object.toString();
}
columnIndex ;
}
csvBuilder.createRow(row);
}
Метод initCsvFile:
public void initCsvFile() {
try {
writer = new CSVWriter(new FileWriter(filePath), ';', CSVWriter.NO_QUOTE_CHARACTER);
} catch (IOException e) {
logger.error("CsvBuilder : error when creating {}", filePath, e);
throw new CsvException("Error when creating the file : " filePath, e);
}
}
Метод createRow:
public void createRow(String[] row) {
writer.writeNext(row);
}
Проблема в том, что у меня есть некоторые данные, которые включают разделитель ‘;’, как показано ниже,
id col1 col2
1 US United;States
К сожалению, файл CSV разделяет Соединенные Штаты на две части . Как я могу проверить содержимое результирующего набора и избежать разделителя без изменения всей программы, чтобы получить Объединенные состояния в одной строке?
Спасибо за вашу помощь
Комментарии:
1. Я бы использовал replace() для замены «;», если потеря его из исходных данных не является проблемой.
Ответ №1:
В этих случаях вам понадобится некоторый символ кавычки, иначе возникнет двусмысленность; в вашем случае вы указываете ему не использовать кавычки, и в результате у него нет способа обработать эти случаи.
Попробуйте явно определить символ кавычки:
public void initCsvFile() {
try {
writer = new CSVWriter(new FileWriter(filePath), ';', '"');
} catch (IOException e) {
logger.error("CsvBuilder : error when creating {}", filePath, e);
throw new CsvException("Error when creating the file : " filePath, e);
}
}
Имейте в виду, что в этом случае любые данные, которые могут вызвать двусмысленность, будут заключены в кавычки:
1;US;"United;States"
Это допустимый CSV, и большинство анализаторов CSV автоматически удаляют кавычки при чтении.
Комментарии:
1. Это правильно, но я получаю в файле CSV ‘ » ‘, окружающем каждый элемент… Полагаю, у меня нет выбора. спасибо 🙂
Ответ №2:
вы могли бы заменить «;» перед созданием CSV-строк, подобных этой
while (resultSet.next()) {
String[] row = new String[resultSetColumnCount];
int columnIndex = 1;
while (columnIndex <= resultSetColumnCount) {
Object object = resultSet.getObject(columnIndex);
if (object == null) {
row[columnIndex - 1] = "";
} else {
// replace ";" by ""
row[columnIndex - 1] = object.toString().replace(";", "");
}
columnIndex ;
}
csvBuilder.createRow(row);
}
Комментарии:
1. Пока потеря этих точек с запятой не является проблемой, это может быть хорошим решением.
2. К сожалению, я не могу потерять точки с запятой, но все же спасибо
Ответ №3:
Я только что столкнулся с аналогичной проблемой. По-видимому, строка должна быть экранирована двойными кавычками, чтобы предотвратить такие проблемы. Итак, я создал escapeCSVDatum()
функцию:
private static String escapeCSVDatum(String s){
return """ s.replace(""", """").replace("n", " ") """;
}
Итак, в вашем случае это было бы применимо здесь
} else {
row[columnIndex - 1] = escapeCSVDatum(object.toString());
}
Однако, как указано Haroldo_OK, ваше использование CSVWriter.NO_QUOTE_CHARACTER
делает невозможным надлежащее рассмотрение таких случаев. Невозможно иметь точку с запятой в datum с этим атрибутом.
Таким образом, вы можете захотеть изменить свой код, чтобы заменить точки с запятой пробелами, например
} else {
row[columnIndex - 1] = object.toString().replace(";"," ");
}
Наконец, если вы хотите возиться с людьми, замените точки с запятой греческими вопросительными знаками.
Комментарии:
1. На данный момент я не могу заменить точки с запятой, но спасибо 🙂