Я пытаюсь разделить текст в 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");
}
Что ты действительно хочешь делать? - разрывать строки по мере их ввода в JTextArea? - найти, где JTextArea выполняет перенос строк? - ???




Это должно охватывать вас:
String lines[] = string.split("\\r?\\n");
На самом деле вам нужно беспокоиться только о двух символах новой строки (UNIX и Windows).
Документ JTextArea ДОЛЖЕН использовать только '\ n'; его представления полностью игнорируют '\ r'. Но если вы собираетесь искать более одного вида разделителей, вы можете также искать все три: «\ r? \ N | \ r».
Mac 9 использует \ r. OSX 10 использует \ n
$ {fn: length (fn: split (data, '\\ r? \\ n'))} не работает в jstl
Не правда ли: 'String [] lines = String.split ("\\ r? \\ n");' ?
@antak да, split по умолчанию удаляет завершающие пустые строки, если они являются результатом разделения. Чтобы отключить этот механизм, вам нужно использовать перегруженную версию split(regex, limit) с отрицательным лимитом, например text.split("\\r?\\n", -1). Более подробная информация: Разделение строки Java удалило пустые значения
String [] lines = string.split (System.getProperty ("line.separator")); Это будет работать нормально, пока вы используете строки, сгенерированные в той же ОС / приложении, но если, например, вы запускаете свое Java-приложение под Linux и извлекаете текст из базы данных, который был сохранен как текст Windows, тогда это может потерпеть неудачу.
Комментарий @stivlo является дезинформацией, и, к сожалению, он получил так много голосов. Как отметил @ Raekye, OS X (теперь известная как macOS) использовала \ n в качестве разделителя строк с момента ее выпуска в 2001 году. Mac OS 9 была выпущена в 1999 году, и я никогда не видел, чтобы использовалась машина с Mac OS 9 или ниже. в производстве. Ни одна современная операционная система не использует \ r в качестве разделителя строк. НИКОГДА не пишите код, который ожидает, что \ r будет разделителем строк на Mac, за исключением случаев, когда а) вы занимаетесь ретро-вычислениями, б) у вас развернута машина с OS 9 и в) может надежно определить, что машина на самом деле является OS 9.
А что это значит?
Этот ответ не сработал для меня. Я просто использую «Строковые части [] = text.split (« \ n »)» или «Строковые части [] = text.split (System.getProperty (« line.separator »))» в java 8.
А как насчет юникода ?? Символ следующей строки ('\ u0085'), символ-разделитель строк ('\ u2028') или символ-разделитель абзацев ('\ u2029).
как насчет этого: \ v + (один или несколько вертикальных пробелов)
Если вам не нужны пустые строки:
String.split("[\\r\\n]+")
двойные обратные косые черты не нужны, см. раздел «Обратные косые черты, экранирование и кавычки» docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…
@giulio Да, я знаю (см. Понимание регулярных выражений в Java: split («\ t») vs split («\\ t») - когда они оба работают, и когда их следует использовать).
Это сработало на Mac OSX, хотя приведенный выше ответ - нет.
Это тоже сработало для меня. Отличное решение. Это сработало в следующих двух случаях: 1) я проснулся в 3 часа. \ R \ n \ r \ nЯ надеюсь 2) это реальная жизнь \ r \ nтак что я
Это совершенно правильный ответ. Одно небольшое предложение могло бы быть полезным добавить Зачем, это избавит от пустых строк для людей, которые могут быть не так знакомы с регулярным выражением и его поведением. Для всех, кому может быть интересно, это потому, что "+" является жадным оператором и будет соответствовать хотя бы одному, но будет продолжать соответствовать символам '\ r \ n' до тех пор, пока он больше не сможет им соответствовать. Смотрите здесь: regular-expressions.info/repeat.html#greedy
Почему не [\\r?\\n]+?
@tresf Вы не можете использовать кванторы в квадратных скобках.
Приведенный выше код на самом деле не делает ничего видимого - он просто вычисляет, а затем сбрасывает расчет. Это код, который вы использовали, или просто пример для этого вопроса?
попробовать сделать textAreaDoc.insertString (int, String, AttributeSet) в конце?
insertUpdate () - это метод DocumentListener. Предполагая, что OP использует его правильно, попытка изменить документ из метода прослушивателя вызовет исключение. Но вы правы: код в этом вопросе на самом деле ничего не делает.
Может быть, это сработает:
Удалите двойную обратную косую черту из параметра метода разделения:
split = docStr.split("\n");
Не совсем. Когда вы пишете регулярное выражение в виде строкового литерала Java, вы можете использовать «\ n», чтобы передать компилятору регулярного выражения символ перевода строки, или «\\ n», чтобы передать ему escape-последовательность для перевода строки. То же самое касается всех других экранированных пробелов, кроме \ v, который не поддерживается в литералах Java.
@Юваль. Извините, это неверно, вам это вообще не нужно "Обратные косые черты, экранирование и цитирование" docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/…
Вам не нужно использовать двойные escape-символы в группах символов.
Для всех непустых строк используйте:
String.split("[\r\n]+")
Да, конечно. Если им где-то нужно двойное спасение, им это нужно везде. Переходы от пробелов, такие как \r и \n, могут иметь одну или две обратные косые черты; они работают в любом случае.
Двойная обратная косая черта '\\' в коде становится символом '\' и затем передается механизму RegEx, поэтому "[\\r\\n]" в коде становится [\r\n] в памяти, и RegEx обработает это. Я не знаю, как именно Java обрабатывает RegEx, но рекомендуется передавать «чистый» строковый шаблон ASCII механизму RegEx и позволять ему обрабатывать, а не передавать двоичные символы. "[\r\n]" становится (шестнадцатеричным) 0D0A в памяти, и один механизм RegEx может его принять, в то время как другой подавится. Таким образом, суть в том, что даже если Java-версия RegEx не нуждается в них, оставьте двойные косые черты для совместимости.
String.split(System.getProperty("line.separator"));
Это должно быть системно-независимым
Это интересная идея, но вы должны позаботиться о том, чтобы в тексте действительно использовался системный разделитель строк. У меня очень много текстовых файлов под unix (например, XML), которые используют разделители "Windows", и довольно много под Windows, которые используют разделители unix.
Работает даже на android
Файлы, созданные в ОС Windows и переданные в ОС Unix, по-прежнему будут содержать разделители \ r \ n. Я считаю, что лучше перестраховаться и учитывать оба сепаратора.
Это очень проблемный подход! Файл не может происходить из системы, в которой запущен код. Я категорически не одобряю такого рода «системно-независимые» конструкции, которые на самом деле зависят от конкретной системы, исполняющей системы.
@Martin, если у вас есть контроль над развернутой системой, это нормально. Однако, если вы развертываете свой код в облаке и не контролируете его, это не лучший способ сделать это.
@Shervin Это никогда не лучший способ. На самом деле это очень плохая практика. Представьте, что какой-то другой программист вызывает System.setProperty ("line.separator", "у вас нет смысла"); Ваш код не работает. Это может даже быть вызвано аналогичным образом зависимостью, о которой вы ничего не знаете.
Это не сработало, поскольку файл был создан в Unix и разделялся в Windows.
@Martin - "какой-то другой программист вызывает System.setProperty (" line.separator "," у вас нет смысла ");" --- Просто интересно, не нарушит ли такой идиотизм / саботаж многие ожидаемые поведения в JDK библиотеки тоже?
@Rop Я не могу сразу вспомнить ни одного случая, но могут существовать зависимости от системных свойств, которые фактически нарушают код. Я настоятельно рекомендую настройку без использования системных свойств, когда это возможно.
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]);
}
}
}
Это бледнеет по сравнению с другими ответами, которые являются более пояснительными и менее сложными. Не могли бы вы объяснить, чего вы добиваетесь с помощью этого кода, и почему он дает подходящий ответ?
Это не имеет ничего общего с разбиением файла на строки. Попробуйте удалить свой ответ.
Метод 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 пара\n)\t, которая является \u0009)\f)\r)Как вы видите, \r\n помещается в начало регулярного выражения, что гарантирует, что регулярное выражение сначала попытается сопоставить этот пара, и только если это сопоставление не удается, оно будет пытаться сопоставить разделители строк одиночный персонаж.
Поэтому, если вы хотите разделить по разделителю строк, используйте split("\\R").
Если вы не хочу удалять из результирующего массива завершающие пустые строки "", используйте split(regex, limit) с отрицательным параметром limit, например split("\\R", -1).
Если вы хотите рассматривать одну или несколько продолжающихся пустых строк как один разделитель, используйте split("\\R+").
Да, это лучший ответ. К сожалению, вопрос был задан на шесть лет раньше, чем был дан ответ.
Я закончил тем, что разделил на \\R+, чтобы избежать любых символов конца строки, которые не были охвачены одним только \\R.
findmatches. Java 9 неправильно позволяет регулярному выражению, подобному \R\R, соответствовать последовательности \r\n, которая представляет однократная разделительная последовательность. Чтобы решить эту проблему, мы можем написать регулярное выражение типа (?>\u000D\u000A)|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029], которое благодаря атомная группа(?>\u000D\u000A) предотвратит возврат регулярного выражения, которое уже соответствует \r\n, и попытается сопоставить \r и \n отдельно.
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);
Напротив, ответ выше имеет следующие свойства:
В качестве альтернативы предыдущим ответам можно использовать 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());
Я знаю, что это может быть излишним решением.
Или String[] lines = new BufferedReader(...).lines().toArray(String[]::new); для массива вместо списка. В этом решении хорошо то, что BufferedReader знает обо всех типах терминаторов, поэтому он может обрабатывать текст во всех форматах. (Большинство решений на основе регулярных выражений, размещенных здесь, в этом отношении не справляются.)
Это решение устарело с Java 11 и введения метода String.lines ().
Существует три различных соглашения (можно сказать, что это стандарты де-факто) для установки и отображения разрыва строки:
carriage return + line feedline feedcarriage returnВ некоторых текстовых редакторах можно поменять один на другой:

Самый простой способ - это нормализовать до line feed, а затем разделить.
final String[] lines = contents.replace("\r\n", "\n")
.replace("\r", "\n")
.split("\n", -1);
Новый метод lines был представлен в классе String в java-11, который возвращает 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"))
Приведенные выше ответы не помогли мне на Android, благодаря ответу Пшемо, который работал у меня на Android. Я оставлю здесь часть Ответ пшемо:
split("\\\\n")
в чем заключается ошибка? Не говори «не работает», это ничего не значит. Сообщите нам полученную ошибку / результат. Это первый шаг в отладке кода - выяснить, что является неправильным результатом и как ваша программа к этому пришла.