How do I use System.getProperty(“line.separator”).toString()?

I have a Tab-delimited String (representing a table) that is passed to my method. When I print it to the command line, it appears like a table with rows:

http://i.stack.imgur.com/2fAyq.gif

The command window is correctly buffered. My thinking is that there is definitely a new line character before or after each row.

My problem is that I want to split up the incoming string into individual strings representing the rows of the table. So far I have:

private static final String newLine = System.getProperty("line.separator").toString();
private static final String tab = "\t";
private static String[] rows;
...

rows = tabDelimitedTable.split(newLine);    //problem is here

System.out.println();
System.out.println("################### start debug ####################");

System.out.println((tabDelimitedTable.contains(newLine)) ? "True" : "False");

System.out.println("#################### end debug###################");
System.out.println();

output:

################### start debug ####################
False
#################### end debug###################

Obviously there is something in the string telling the OS to start a new line. Yet it apparently contains no newline characters.

Running the latest JDK on Windows XP SP3.

Any Ideas?

21
задан Gray 6 July 2018 в 16:12
поделиться

7 ответов

Попробуйте

rows = tabDelimitedTable.split("[" + newLine + "]");

. Это должно решить проблему регулярного выражения .

Также не так важно, но тип возвращаемого значения

System.getProperty("line.separator")

- String , поэтому вызывать toString () не нужно.

28
ответ дан 29 November 2019 в 06:31
поделиться

В Windows line.separator представляет собой комбинацию CR / LF (ссылка здесь ).

Метод Java String.split () принимает регулярное выражение . Так что я думаю, здесь есть некоторая путаница.

2
ответ дан 29 November 2019 в 06:31
поделиться

Попробуйте BufferedReader.readLine() вместо всех этих сложностей. Он распознает все возможные терминаторы строк.

2
ответ дан 29 November 2019 в 06:31
поделиться

Проблема

Вы должны НЕ считать, что произвольный входной текстовый файл использует "правильный" специфический для платформы newline разделитель. Похоже, это и есть источник вашей проблемы; это имеет мало общего с regex.

Для примера, на платформе Windows System.getProperty("line.separator") - "\r\n" (CR+LF). Однако, когда вы запускаете свой Java-код на этой платформе, вы вполне можете иметь дело с входным файлом, разделитель строк которого просто "\n" (LF). Возможно, этот файл был изначально создан на платформе Unix, а затем передан в двоичном (а не текстовом) режиме в Windows. Может быть много сценариев, в которых вы можете столкнуться с подобными ситуациями, когда вы должны разобрать текстовый файл в качестве входного, который не использует разделитель новой строки текущей платформы.

(По совпадению, когда текстовый файл Windows передается в Unix в двоичном режиме, многие редакторы отображают ^M, что сбивает с толку некоторых людей, которые не понимают, что происходит).

Когда вы производите текстовый файл в качестве выходного, вы, вероятно, должны предпочесть специфический для платформы разделитель новой строки, но когда вы потребляете текстовый файл в качестве входного, вероятно, небезопасно делать предположение, что он правильно использует специфический для платформы разделитель новой строки.


Решение

Одним из способов решения проблемы является использование, например, java.util.Scanner. В нем есть метод nextLine() который может вернуть следующую строку (если она существует), правильно обрабатывая любое несоответствие между разделителем новой строки платформы и входным текстовым файлом.

Вы также можете объединить 2 Scanner, один для сканирования файла построчно, а другой для сканирования токенов каждой строки. Вот простой пример использования, который разбивает каждую строку на List. Таким образом, весь файл становится List>.

Это, вероятно, лучший подход, чем чтение всего файла в одну огромную String, а затем разбиение на строки (которые затем разбиваются на части).

    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]]

См. также

  • Effective Java 2nd Edition, Item 25: Prefer lists to arrays

Похожие вопросы

30
ответ дан 29 November 2019 в 06:31
поделиться

Попробуйте следующее:

rows = tabDelimitedTable.split("[\\r\\n]+");

Это должно работать независимо от того, какие разделители строк используются во вводе, и будет игнорировать пустые строки.

1
ответ дан 29 November 2019 в 06:31
поделиться

Я думаю, ваша проблема в том, что String.split () обрабатывает свой аргумент как регулярное выражение, а регулярные выражения обрабатывают символы новой строки специально. Возможно, вам потребуется явно создать объект регулярного выражения для передачи в split () (есть еще одна его перегрузка) и настроить это регулярное выражение, чтобы разрешить новые строки, передав MULTILINE в параметре флагов Pattern.compile () . Docs

1
ответ дан 29 November 2019 в 06:31
поделиться

Другие респонденты правы, что разделение () принимает в качестве аргумента регулярное выражение, поэтому сначала вам нужно исправить это. Другая проблема заключается в том, что вы предполагаете, что символы разрыва строки такие же, как и в системе по умолчанию. В зависимости от того, откуда поступают данные и где работает программа, это предположение может быть неверным.

1
ответ дан 29 November 2019 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: