Я пытаюсь разделить текст в 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");
}
Это должно охватывать вас:
String lines[] = string.split("\\r?\\n");
Есть только две новые строки (UNIX и Windows), о которых вам нужно беспокоиться.
Если вы не хотите пустые строки:
String.split("[\\r\\n]+")
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]
Поэтому мы можем использовать его для соответствия:
\u000D\000A
→ \r\n
пара\n
)\u0009
символов \t
которая является \u0009
)\f
)\r
) Как вы видите, \r\n
помещается в начало регулярного выражения, что гарантирует, что регулярное выражение будет пытаться сначала сопоставить эту пару, и только если это совпадение не удастся, оно попытается сопоставить разделители отдельных символов.
Поэтому, если вы хотите разделить на разделителе строк, используйте split("\\R")
.
Если вы не хотите удалять из результирующего массива конечные пустые строки ""
используйте split(regex, limit)
с параметром отрицательного limit
например split("\\R", -1)
.
Если вы хотите обрабатывать одну или несколько split("\\R+")
пустых строк, используйте split("\\R+")
.
String.split(System.getProperty("line.separator"));
Это должно быть независимым от системы
Вам не нужно удваивать символы escape в символьных группах.
Для всех непустых строк используйте:
String.split("[\r\n]+")
\r
и \n
могут иметь один или два обратных слеша; они работают в любом случае.
'\\'
в коде становится символом '\'
и затем передается в механизм RegEx, поэтому "[\\r\\n]"
в коде становится [\r\n]
в памяти, и RegEx будет обрабатывать тот. Я не знаю, как именно Java обрабатывает RegEx, но хорошей практикой является передача «чистого» строкового шаблона ASCII в движок RegEx и его обработка, а не передача двоичных символов. "[\r\n]"
становится (шестнадцатеричным) 0D0A
в памяти, и один механизм RegEx может принять его, а другой задохнется. Таким образом, суть в том, что даже если Java-версия RegEx не нуждается в них, сохраняйте двойную косую черту для совместимости
Возможно, это сработает:
Удалите двойные обратные косые черты из параметра метода split:
split = docStr.split("\n");
Новые lines
методов были введены в класс String
в java-11, который возвращает 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
Все приведенные здесь ответы фактически не соответствуют определению Javas новых строк, как указано в BufferedReader # Readline. Java принимает \n
, \r
и \r\n
как новую строку. Некоторые ответы соответствуют нескольким пустым строкам или искаженным файлам. Например. <sometext>\n\r\n<someothertext>
при использовании [\r\n]+
приведет к двум строкам.
String lines[] = string.split("(\r\n|\r|\n)", -1);
Напротив, ответ выше имеет следующие свойства:
Для сохранения пустых строк от раздавливания используйте:
String lines[] = String.split("\\r?\\n", -1);
Вышеприведенный код фактически ничего не делает - он просто вычисляет, а затем выдает расчет. Это код, который вы использовали, или просто пример для этого вопроса?
попробуйте сделать textAreaDoc.insertString(int, String, AttributeSet) в конце?
Если по какой-то причине вы не хотите использовать 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
знает обо всех подобных терминаторах, поэтому он может обрабатывать текст во всех видах форматов. (Большинство решений на основе регулярных выражений, размещенных здесь, в этом отношении не дотягивают.)
В качестве альтернативы предыдущим ответам API guava Splitter
может использоваться, если к результирующим строкам будут применяться другие операции, такие как обрезка линий или фильтрация пустых строк:
import com.google.common.base.Splitter;
Iterable<String> split = Splitter.onPattern("\r?\n").trimResults().omitEmptyStrings().split(docStr);
Обратите внимание, что результатом является Iterable
, а не массив.
После неудачных попыток на основе всех данных решений. Я заменяю \n
некоторым специальным словом, а затем разделяю. Для меня следующий трюк:
article = "Alice phoned\n bob.";
article = article.replace("\\n", " NEWLINE ");
String sen [] = article.split(" NEWLINE ");
Я не смог воспроизвести пример, приведенный в вопросе. Но, я думаю, эта логика может быть применена.
String lines[] =String.split( System.lineSeparator())
В 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 для множества вариантов для вас, поскольку он позволяет писать краткое и декларативное выражение возможных параллельных операций.
В городе есть новый мальчик, поэтому вам не нужно заниматься всеми вышеперечисленными сложностями. Начиная с 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/
Надеюсь, это кому-то поможет. Счастливое кодирование.
Существует три разных соглашения (можно сказать, что они являются стандартами де-факто) для установки и отображения разрыва строки:
carriage return
+ line feed
line feed
carriage return
В некоторых текстовых редакторах можно обменять один на другой:
Самое простое - нормализовать line feed
и затем расколоть.
final String[] lines = contents.replace("\r\n", "\n")
.replace("\r", "\n")
.split("\n", -1);
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");
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]);
}
}
}