Проблема
Вы не должны НЕ предполагать, что произвольный входной текстовый файл использует "правильный" для конкретной платформы разделитель новой строки. Похоже, это источник вашей проблемы; это не имеет ничего общего с регулярным выражением.
Чтобы проиллюстрировать, на платформе Windows System.getProperty("line.separator")
равно "\r\n"
(CR + LF). Однако, когда вы запускаете свой Java-код на этой платформе, вам, возможно, придется иметь дело с входным файлом, разделителем строк которого является просто "\n"
(LF). Возможно, этот файл изначально был создан на платформе Unix, а затем перенесен в Windows в двоичном (а не текстовом) режиме. Может быть много сценариев, в которых вы можете столкнуться с подобными ситуациями, когда вы должны проанализировать текстовый файл как ввод, который не использует разделитель новой строки текущей платформы.
(По совпадению, когда текстовый файл Windows передается в Unix в двоичном режиме, многие редакторы отображают ^M
, что сбивает с толку некоторых людей, которые не понимают, что происходит).
Когда вы создаете текстовый файл в качестве вывода, вам, вероятно, следует предпочесть разделитель новой строки, зависящий от платформы, но когда вы потребляете текстовый файл в качестве ввода, это, вероятно, небезопасно чтобы сделать предположение, что он правильно использует разделитель новой строки, специфичный для платформы.
Решение
Один из способов решить проблему - использовать, например, java.util.Scanner
. У него есть _6 _ метод>, который может возвращать следующую строку (если она существует), правильно обрабатывая любые несоответствия между разделителем новой строки платформы и входным текстовым файлом.
Вы также можете комбинировать 2 Scanner
, один для построчного сканирования файла, а другой для сканирования маркеров каждой строки. Вот простой пример использования, который разбивает каждую строку на List<String>
. Таким образом, весь файл становится List<List<String>>
.
Это, вероятно, лучший подход, чем чтение всего файла в один огромный String
, а затем split
на строки (которые затем split
на части).
String text
= "row1\tblah\tblah\tblah\n"
+ "row2\t1\t2\t3\t4\r\n"
+ "row3\tA\tB\tC\r"
+ "row4";
System.out.println(text);
// row1 blah blah blah
// row2 1 2 3 4
// row3 A B C
// row4
List<List<String>> input = new ArrayList<List<String>>();
Scanner sc = new Scanner(text);
while (sc.hasNextLine()) {
Scanner lineSc = new Scanner(sc.nextLine()).useDelimiter("\t");
List<String> line = new ArrayList<String>();
while (lineSc.hasNext()) {
line.add(lineSc.next());
}
input.add(line);
}
System.out.println(input);
// [[row1, blah, blah, blah], [row2, 1, 2, 3, 4], [row3, A, B, C], [row4]]
Смотрите также
- Эффективная версия Java 2nd Edition, пункт 25: Предпочитайте списки массивам
Связанные вопросы
person
polygenelubricants
schedule
19.08.2010