Разделить строку Java на новую строку

Я пытаюсь разделить текст в JTextArea с помощью регулярного выражения для разделения строки с помощью \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");
}

в чем заключается ошибка? Не говори «не работает», это ничего не значит. Сообщите нам полученную ошибку / результат. Это первый шаг в отладке кода - выяснить, что является неправильным результатом и как ваша программа к этому пришла.

Chii 18.01.2009 13:18

Что ты действительно хочешь делать? - разрывать строки по мере их ввода в JTextArea? - найти, где JTextArea выполняет перенос строк? - ???

user85421 29.04.2009 16:05
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
411
2
572 781
20
Перейти к ответу Данный вопрос помечен как решенный

Ответы 20

Ответ принят как подходящий

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

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

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

Документ JTextArea ДОЛЖЕН использовать только '\ n'; его представления полностью игнорируют '\ r'. Но если вы собираетесь искать более одного вида разделителей, вы можете также искать все три: «\ r? \ N | \ r».

Alan Moore 18.01.2009 21:02

Mac 9 использует \ r. OSX 10 использует \ n

Raekye 06.05.2013 09:25

$ {fn: length (fn: split (data, '\\ r? \\ n'))} не работает в jstl

user2538100 17.06.2014 19:48

Не правда ли: 'String [] lines = String.split ("\\ r? \\ n");' ?

FeinesFabi 30.10.2014 13:45

@antak да, split по умолчанию удаляет завершающие пустые строки, если они являются результатом разделения. Чтобы отключить этот механизм, вам нужно использовать перегруженную версию split(regex, limit) с отрицательным лимитом, например text.split("\\r?\\n", -1). Более подробная информация: Разделение строки Java удалило пустые значения

Pshemo 19.07.2016 16:08

String [] lines = string.split (System.getProperty ("line.separator")); Это будет работать нормально, пока вы используете строки, сгенерированные в той же ОС / приложении, но если, например, вы запускаете свое Java-приложение под Linux и извлекаете текст из базы данных, который был сохранен как текст Windows, тогда это может потерпеть неудачу.

ibai 25.03.2017 02:40

Комментарий @stivlo является дезинформацией, и, к сожалению, он получил так много голосов. Как отметил @ Raekye, OS X (теперь известная как macOS) использовала \ n в качестве разделителя строк с момента ее выпуска в 2001 году. Mac OS 9 была выпущена в 1999 году, и я никогда не видел, чтобы использовалась машина с Mac OS 9 или ниже. в производстве. Ни одна современная операционная система не использует \ r в качестве разделителя строк. НИКОГДА не пишите код, который ожидает, что \ r будет разделителем строк на Mac, за исключением случаев, когда а) вы занимаетесь ретро-вычислениями, б) у вас развернута машина с OS 9 и в) может надежно определить, что машина на самом деле является OS 9.

James McLaughlin 04.05.2017 01:53

А что это значит?

Lealo 09.08.2017 02:22

Этот ответ не сработал для меня. Я просто использую «Строковые части [] = text.split (« \ n »)» или «Строковые части [] = text.split (System.getProperty (« line.separator »))» в java 8.

Maykel Llanes Garcia 05.12.2017 00:24

А как насчет юникода ?? Символ следующей строки ('\ u0085'), символ-разделитель строк ('\ u2028') или символ-разделитель абзацев ('\ u2029).

john ktejik 11.11.2018 03:10

как насчет этого: \ v + (один или несколько вертикальных пробелов)

Ubeogesh 14.01.2020 17:17

Если вам не нужны пустые строки:

String.split("[\\r\\n]+")

двойные обратные косые черты не нужны, см. раздел «Обратные косые черты, экранирование и кавычки» docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…

angryITguy 06.12.2011 02:09

Это сработало на Mac OSX, хотя приведенный выше ответ - нет.

John 02.11.2014 02:57

Это тоже сработало для меня. Отличное решение. Это сработало в следующих двух случаях: 1) я проснулся в 3 часа. \ R \ n \ r \ nЯ надеюсь 2) это реальная жизнь \ r \ nтак что я

logixplayer 17.07.2015 18:52

Это совершенно правильный ответ. Одно небольшое предложение могло бы быть полезным добавить Зачем, это избавит от пустых строк для людей, которые могут быть не так знакомы с регулярным выражением и его поведением. Для всех, кому может быть интересно, это потому, что "+" является жадным оператором и будет соответствовать хотя бы одному, но будет продолжать соответствовать символам '\ r \ n' до тех пор, пока он больше не сможет им соответствовать. Смотрите здесь: regular-expressions.info/repeat.html#greedy

greyseal96 08.04.2016 23:54

Почему не [\\r?\\n]+?

tresf 21.02.2019 21:19

@tresf Вы не можете использовать кванторы в квадратных скобках.

CX gamer 11.12.2019 11:58

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

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

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

Alan Moore 18.01.2009 20:55

Может быть, это сработает:

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

split = docStr.split("\n");

Не совсем. Когда вы пишете регулярное выражение в виде строкового литерала Java, вы можете использовать «\ n», чтобы передать компилятору регулярного выражения символ перевода строки, или «\\ n», чтобы передать ему escape-последовательность для перевода строки. То же самое касается всех других экранированных пробелов, кроме \ v, который не поддерживается в литералах Java.

Alan Moore 18.01.2009 23:55

@Юваль. Извините, это неверно, вам это вообще не нужно "Обратные косые черты, экранирование и цитирование" docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…

angryITguy 06.12.2011 02:10

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

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

String.split("[\r\n]+")

Да, конечно. Если им где-то нужно двойное спасение, им это нужно везде. Переходы от пробелов, такие как \r и \n, могут иметь одну или две обратные косые черты; они работают в любом случае.

Alan Moore 06.06.2016 22:09

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

nurchi 15.09.2016 20:31
String.split(System.getProperty("line.separator"));

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

Это интересная идея, но вы должны позаботиться о том, чтобы в тексте действительно использовался системный разделитель строк. У меня очень много текстовых файлов под unix (например, XML), которые используют разделители "Windows", и довольно много под Windows, которые используют разделители unix.

Maarten Bodewes 31.07.2012 03:37

Работает даже на android

ruX 07.03.2014 17:23

Файлы, созданные в ОС Windows и переданные в ОС Unix, по-прежнему будут содержать разделители \ r \ n. Я считаю, что лучше перестраховаться и учитывать оба сепаратора.

bvdb 18.07.2014 15:44

Это очень проблемный подход! Файл не может происходить из системы, в которой запущен код. Я категорически не одобряю такого рода «системно-независимые» конструкции, которые на самом деле зависят от конкретной системы, исполняющей системы.

Martin 11.12.2014 11:38

@Martin, если у вас есть контроль над развернутой системой, это нормально. Однако, если вы развертываете свой код в облаке и не контролируете его, это не лучший способ сделать это.

Shervin Asgari 11.12.2014 15:56

@Shervin Это никогда не лучший способ. На самом деле это очень плохая практика. Представьте, что какой-то другой программист вызывает System.setProperty ("line.separator", "у вас нет смысла"); Ваш код не работает. Это может даже быть вызвано аналогичным образом зависимостью, о которой вы ничего не знаете.

Martin 16.12.2014 16:34

Это не сработало, поскольку файл был создан в Unix и разделялся в Windows.

Greg 06.10.2015 20:06

@Martin - "какой-то другой программист вызывает System.setProperty (" line.separator "," у вас нет смысла ");" --- Просто интересно, не нарушит ли такой идиотизм / саботаж многие ожидаемые поведения в JDK библиотеки тоже?

Rop 13.07.2017 16:52

@Rop Я не могу сразу вспомнить ни одного случая, но могут существовать зависимости от системных свойств, которые фактически нарушают код. Я настоятельно рекомендую настройку без использования системных свойств, когда это возможно.

Martin 15.08.2017 17:53
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]);
        }
    }

}

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

Makoto 19.05.2014 04:24

Это не имеет ничего общего с разбиением файла на строки. Попробуйте удалить свой ответ.

Martin 11.12.2014 11:47

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

Linebreak matcher
\R         Any Unicode linebreak sequence, is equivalent to \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Таким образом, мы можем использовать его для сопоставления:

  • \u000D\000A -> \r\n пара
  • \ u000A -> перевод строки (\n)
  • \ u000B -> табуляция строк (НЕ путать с таблица символов \t, которая является \u0009)
  • \ u000C -> подача формы (\f)
  • \ u000D -> возврат каретки (\r)
  • \ u0085 -> следующая строка (NEL)
  • \ u2028 -> разделитель строк
  • \ u2029 -> разделитель абзацев

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


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

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

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

Да, это лучший ответ. К сожалению, вопрос был задан на шесть лет раньше, чем был дан ответ.

Dawood ibn Kareem 22.11.2019 06:20

Я закончил тем, что разделил на \\R+, чтобы избежать любых символов конца строки, которые не были охвачены одним только \\R.

SeverityOne 21.01.2020 09:45
ПРОБЛЕМА JAVA 9 с findmatches. Java 9 неправильно позволяет регулярному выражению, подобному \R\R, соответствовать последовательности \r\n, которая представляет однократная разделительная последовательность. Чтобы решить эту проблему, мы можем написать регулярное выражение типа (?>\u000D\u000A)|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029‌​], которое благодаря атомная группа(?>\u000D\u000A) предотвратит возврат регулярного выражения, которое уже соответствует \r\n, и попытается сопоставить \r и \n отдельно.
Pshemo 29.01.2021 15:23

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

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

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

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

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

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

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

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

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

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

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

import com.google.common.base.Splitter;

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

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

  • Попробуй, надеюсь, это было полезно для тебя

 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");

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

List<String> lines = new BufferedReader(new StringReader(string))
        .lines()
        .collect(Collectors.toList());

Я знаю, что это может быть излишним решением.

Danilo Piazzalunga 07.03.2018 22:52

Или String[] lines = new BufferedReader(...).lines().toArray(String[]::new); для массива вместо списка. В этом решении хорошо то, что BufferedReader знает обо всех типах терминаторов, поэтому он может обрабатывать текст во всех форматах. (Большинство решений на основе регулярных выражений, размещенных здесь, в этом отношении не справляются.)

Ted Hopp 25.04.2018 06:48

Это решение устарело с Java 11 и введения метода String.lines ().

leventov 04.10.2018 03:22

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

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

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

Notepad++

Самый простой способ - это нормализовать до line feed, а затем разделить.

final String[] lines = contents.replace("\r\n", "\n")
                               .replace("\r", "\n")
                               .split("\n", -1);

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

Returns a stream of substrings extracted from this string partitioned by line terminators.

Line terminators recognized are line feed "\n" (U+000A), carriage return "\r" (U+000D) and a carriage return followed immediately by a line feed "\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

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

В городе появился новый мальчик, так что вам не придется сталкиваться со всеми вышеперечисленными сложностями. Начиная с 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/en/java/javase/11/docs/api/java.base/java/lang/String.html#lines ()https://www.azul.com/90-new-features-and-apis-in-jdk-11/

Надеюсь, это будет кому-то полезно. Удачного кодирования.

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

Returning a stream of lines extracted from this string, separated by line terminators.

Далее документация продолжает:

A line terminator is one of the following: a line feed character "\n" (U+000A), a carriage return character "\r" (U+000D), or a carriage return followed immediately by a line feed "\r\n" (U+000D U+000A). A line is either a sequence of zero or more characters followed by a line terminator, or it is a sequence of one or more characters followed by the end of the string. A line does not include the line terminator.

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

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

тогда, если вам нужен массив:

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

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

это работает для java8 и разбивает строку на поток строк строк: Arrays.stream (str.split ("\\ n"))

MichaelMoser 04.01.2021 01:51

Приведенные выше ответы не помогли мне на Android, благодаря ответу Пшемо, который работал у меня на Android. Я оставлю здесь часть Ответ пшемо:

split("\\\\n")

Другие вопросы по теме