Разделенная строка Java новой строкой

335

Я пытаюсь разделить текст в JTextArea с помощью регулярного выражения, чтобы разделить String на \n. Однако это не работает, и я также пробовал \r\n|\r|n и многие другие комбинации регулярных выражений. Код:

public void insertUpdate(DocumentEvent e) {
    String split[], docStr = null;
    Document textAreaDoc = (Document)e.getDocument();

    try {
        docStr = textAreaDoc.getText(textAreaDoc.getStartPosition().getOffset(), textAreaDoc.getEndPosition().getOffset());
    } catch (BadLocationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    split = docStr.split("\\n");
}
  • 7
    какую ошибку вы получаете? Не говори "не работает", это ничего не значит. Сообщите нам ошибку / результат, который вы получите. Это первый шаг в отладке кода - выясните, что является неправильным результатом, и как ваша программа достигла этого.
  • 0
    Что вы действительно хотите сделать? - разрыв строки, как они введены в JTextArea? найти, где JTextArea делает переносы строк? - ???
Теги:
split
newline

19 ответов

637
Лучший ответ

Это должно охватывать вас:

String lines[] = string.split("\\r?\\n");

Есть только две новые строки (UNIX и Windows), о которых вам нужно беспокоиться.

  • 40
    Документ JTextArea ДОЛЖЕН использовать только '\ n'; его взгляды полностью игнорируют '\ r'. Но если вы собираетесь искать более одного вида разделителя, вы можете также искать все три: "\ r? \ N | \ r".
  • 10
    Mac 9 использует \ r. OSX 10 использует \ n
Показать ещё 9 комментариев
118

Если вы не хотите пустые строки:

String.split("[\\r\\n]+")
  • 4
    двойная обратная косая черта не нужна, см. раздел «Обратная косая черта, экранирование и цитирование» docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…
Показать ещё 4 комментария
88

split метод использует регулярное выражение (регулярное выражение). Так как Java 8 regex поддерживает \R который представляет (из документации класса Pattern):

Разделитель строк
\R Любая последовательность \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029] Unicode, эквивалентна \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Поэтому мы можем использовать его для соответствия:

Как вы видите, \r\n помещается в начало регулярного выражения, что гарантирует, что регулярное выражение будет пытаться сначала сопоставить эту пару, и только если это совпадение не удастся, оно попытается сопоставить разделители отдельных символов.


Поэтому, если вы хотите разделить на разделителе строк, используйте split("\\R").

Если вы не хотите удалять из результирующего массива конечные пустые строки "" используйте split(regex, limit) с параметром отрицательного limit например split("\\R", -1).

Если вы хотите обрабатывать одну или несколько split("\\R+") пустых строк, используйте split("\\R+").

43
String.split(System.getProperty("line.separator"));

Это должно быть независимым от системы

  • 39
    Это интересная идея, но вы должны позаботиться о том, чтобы текст действительно использовал системный разделитель строк. У меня есть много текстовых файлов в Unix (например, XML), которые используют разделители «Windows», и довольно много в Windows, которые используют разделители Unix.
  • 0
    Работает даже на андроид
Показать ещё 8 комментариев
11

Вам не нужно удваивать символы escape в символьных группах.

Для всех непустых строк используйте:

String.split("[\r\n]+")
  • 0
    Да, вы делаете. Если им нужно куда-то сбежать, им это нужно везде. Пробелы, такие как \r и \n могут иметь один или два обратных слеша; они работают в любом случае.
  • 2
    Двойная обратная косая черта '\\' в коде становится символом '\' и затем передается в механизм RegEx, поэтому "[\\r\\n]" в коде становится [\r\n] в памяти, и RegEx будет обрабатывать тот. Я не знаю, как именно Java обрабатывает RegEx, но хорошей практикой является передача «чистого» строкового шаблона ASCII в движок RegEx и его обработка, а не передача двоичных символов. "[\r\n]" становится (шестнадцатеричным) 0D0A в памяти, и один механизм RegEx может принять его, а другой задохнется. Таким образом, суть в том, что даже если Java-версия RegEx не нуждается в них, сохраняйте двойную косую черту для совместимости
7

Возможно, это сработает:

Удалите двойные обратные косые черты из параметра метода split:

split = docStr.split("\n");
  • 0
    плохая идея - вам нужен обратный слеш для побега ...
  • 8
    На самом деле, нет. Когда вы пишете регулярное выражение в форме литерала Java String, вы можете использовать "\ n", чтобы передать компилятору регулярного выражения символ перевода строки, или "\\ n", чтобы передать ему escape-последовательность для перевода строки. То же самое касается всех других пробелов, кроме \ v, что не поддерживается в литералах Java.
Показать ещё 1 комментарий
4

Новые lines методов были введены в класс String в , который возвращает Stream<String>

Возвращает поток подстрок, извлеченных из этой строки, разделенной терминаторами строк.

Определяемые линейные терминаторы - это строка "\n" (U + 000A), возврат каретки "\ r" (U + 000D) и возврат каретки, за которым сразу следует строка "\ r\n" (U + 000D U + 000A).

Вот несколько примеров:

jshell> "lorem \n ipusm \n sit".lines().forEach(System.out::println)
lorem
 ipusm
 sit

jshell> "lorem \n ipusm \r  sit".lines().forEach(System.out::println)
lorem
 ipusm
  sit

jshell> "lorem \n ipusm \r\n  sit".lines().forEach(System.out::println)
lorem
 ipusm
  sit

Строка # строки()

4

Все приведенные здесь ответы фактически не соответствуют определению Javas новых строк, как указано в BufferedReader # Readline. Java принимает \n, \r и \r\n как новую строку. Некоторые ответы соответствуют нескольким пустым строкам или искаженным файлам. Например. <sometext>\n\r\n<someothertext> при использовании [\r\n]+ приведет к двум строкам.

String lines[] = string.split("(\r\n|\r|\n)", -1);

Напротив, ответ выше имеет следующие свойства:

  • он соответствует определению Javas новой строки, например, BufferedReader использует его
  • он не соответствует нескольким новым строкам
  • он не удаляет завершающие пустые строки
4

Для сохранения пустых строк от раздавливания используйте:

String lines[] = String.split("\\r?\\n", -1);
3

Вышеприведенный код фактически ничего не делает - он просто вычисляет, а затем выдает расчет. Это код, который вы использовали, или просто пример для этого вопроса?

попробуйте сделать textAreaDoc.insertString(int, String, AttributeSet) в конце?

  • 0
    insertUpdate () является методом DocumentListener. Предполагая, что OP использует его правильно, попытка изменить документ из метода слушателя вызовет исключение. Но вы правы: код в этом вопросе на самом деле ничего не делает.
  • 0
    Просто пример.
2

Если по какой-то причине вы не хотите использовать String.split (например, из-за регулярных выражений) и хотите использовать функциональное программирование на Java 8 или новее:

List<String> lines = new BufferedReader(new StringReader(string))
        .lines()
        .collect(Collectors.toList());
  • 0
    Я знаю, что это может быть излишним решением.
  • 0
    Или String[] lines = new BufferedReader(...).lines().toArray(String[]::new); для массива вместо списка. Приятной особенностью этого решения является то, что BufferedReader знает обо всех подобных терминаторах, поэтому он может обрабатывать текст во всех видах форматов. (Большинство решений на основе регулярных выражений, размещенных здесь, в этом отношении не дотягивают.)
Показать ещё 1 комментарий
1

В качестве альтернативы предыдущим ответам API guava Splitter может использоваться, если к результирующим строкам будут применяться другие операции, такие как обрезка линий или фильтрация пустых строк:

import com.google.common.base.Splitter;

Iterable<String> split = Splitter.onPattern("\r?\n").trimResults().omitEmptyStrings().split(docStr);

Обратите внимание, что результатом является Iterable, а не массив.

1

После неудачных попыток на основе всех данных решений. Я заменяю \n некоторым специальным словом, а затем разделяю. Для меня следующий трюк:

article = "Alice phoned\n bob.";
article = article.replace("\\n", " NEWLINE ");
String sen [] = article.split(" NEWLINE ");

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

1

String lines[] =String.split( System.lineSeparator())

0

В JDK11 класс String имеет метод lines():

Возврат потока строк, извлеченных из этой строки, разделенных терминаторами строк.

Далее, в документации говорится:

Терминатор линии является одним из следующих: символ строки "\n" (U + 000A), символ возврата каретки "\ r" (U + 000D) или возврат каретки, сразу же следуя строкой "\ r\n "(U + 000D U + 000A). Строка представляет собой последовательность из нуля или более символов, за которой следует ограничитель строки, или последовательность из одного или нескольких символов, за которыми следует конец строки. Строка не включает терминатор линии.

С этим можно просто сделать:

Stream<String> stream = str.lines();

то, если вы хотите массив:

String[] array = str.lines().toArray(String[]::new);

Учитывая этот метод, он возвращает Stream для множества вариантов для вас, поскольку он позволяет писать краткое и декларативное выражение возможных параллельных операций.

0

В городе есть новый мальчик, поэтому вам не нужно заниматься всеми вышеперечисленными сложностями. Начиная с JDK 11, нужно просто написать как одну строку кода, она разделит строки и вернет вам Stream of String.

public class MyClass {
public static void main(String args[]) {
   Stream<String> lines="foo \n bar \n baz".lines();
   //Do whatever you want to do with lines
}}

Некоторые ссылки. https://docs.oracle.com/ru/java/javase/11/docs/api/java.base/java/lang/String.html#lines() https://www.azul.com/90-new -Особенности-и-АПИС-в-JDK-11/

Надеюсь, это кому-то поможет. Счастливое кодирование.

0

Существует три разных соглашения (можно сказать, что они являются стандартами де-факто) для установки и отображения разрыва строки:

  • carriage return + line feed
  • line feed
  • carriage return

В некоторых текстовых редакторах можно обменять один на другой:

Изображение 4737

Самое простое - нормализовать line feed и затем расколоть.

final String[] lines = contents.replace("\r\n", "\n")
                               .replace("\r", "\n")
                               .split("\n", -1);
0
  • попробуйте эту надежду, это было полезно для вас.

 String split[], docStr = null;
Document textAreaDoc = (Document)e.getDocument();

try {
    docStr = textAreaDoc.getText(textAreaDoc.getStartPosition().getOffset(), textAreaDoc.getEndPosition().getOffset());
} catch (BadLocationException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

split = docStr.split("\n");
-3
package in.javadomain;

public class JavaSplit {

    public static void main(String[] args) {
        String input = "chennai\nvellore\ncoimbatore\nbangalore\narcot";
        System.out.println("Before split:\n");
        System.out.println(input);

        String[] inputSplitNewLine = input.split("\\n");
        System.out.println("\n After split:\n");
        for(int i=0; i<inputSplitNewLine.length; i++){
            System.out.println(inputSplitNewLine[i]);
        }
    }

}
  • 0
    Это бледнеет по сравнению с другими ответами, которые более понятны и менее трудоемки. Не могли бы вы объяснить, что вы делаете с этим кодом, и почему он может дать подходящий ответ?
  • 2
    Это не имеет ничего общего с разбиением файла на строки. Попробуйте удалить свой ответ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню