В ответе Барта Киерса отсутствует крайний случай, когда последняя строка строки пуста или содержит пробелы.
Если вы попробуете
String text = "line 1\n\nline 3\n\n\nline 5\n "; // <-- Mind the \n plus space at the end!
String adjusted = text.replaceAll("(?m)^[ \t]*\r?\n", "");
вы получите строку, равную этому
"line 1\nline 3\nline 5\n " // <-- MIND the \n plus space at the end!
как результат.
Я расширил Барт Киерс 'ответ, чтобы также охватить этот случай.
Мой шаблон регулярных выражений:
String pattern = "(?m)^\\s*\\r?\\n|\\r?\\n\\s*(?!.*\\r?\\n)";
Небольшое объяснение:
Первая часть шаблона в основном совпадает с Bart Kiers '. Это нормально, но не удаляет «пустую» последнюю или последнюю строку, содержащую пробелы.
Это потому, что последняя строка, содержащая только пробелы, не заканчивается на \\r?\\n
и поэтому не будет сопоставлена / заменена. Нам нужно что-то, чтобы выразить этот крайний случай. Вот тут и начинается вторая часть (после |
).
Используется специальность регулярного выражения: отрицательный взгляд . Это (?!.*\\r?\\n)
часть шаблона. (?!
отмечает начало предвкушения. Вы можете прочитать его так: Сопоставить регулярное выражение перед заглядыванием, если за ним не следует то, что определено как строка, которая не должна следовать. В нашем случае: ни один символ (ноль или более раз), за которым следует возврат каретки (0 или 1 раз) и символ новой строки: .*\\r?\\n
. )
закрывает взгляд. Само предчувствие не является частью матча.
Если я выполню следующий фрагмент кода:
String pattern = "(?m)^\\s*\\r?\\n|\\r?\\n\\s*(?!.*\\r?\\n)";
String replacement = "";
String inputString =
"\n" +
"Line 2 - above line is empty without spaces\n" +
"Line 3 - next is empty without whitespaces\n" +
"\n" +
"Line 5 - next line is with whitespaces\n" +
" \n" +
"Line 7 - next 2 lines are \"empty\". First one with whitespaces.\n" +
" \r\n" +
"\n" +
"Line 10 - 3 empty lines follow. The 2nd one with whitespaces in it. One whitespace at the end of this line " +
"\n" +
" \n" +
"\n";
String ajdustedString = inputString.replaceAll(pattern, replacement);
System.out.println("inputString:");
System.out.println("+----");
System.out.println(inputString);
System.out.println("----+");
System.out.println("ajdustedString:");
System.out.println("+----");
System.out.print(ajdustedString); //MIND the "print" instead of "println"
System.out.println("|EOS"); //String to clearly mark the _E_nd _O_f the adjusted_S_tring
System.out.println("----+");
Я получаю:
inputString:
+----
Line 2 - above line is empty without spaces
Line 3 - next is empty without whitespaces
Line 5 - next line is with whitespaces
Line 7 - next 2 lines are "empty". First one with whitespaces.
Line 10 - 3 empty lines follow. The 2nd one with whitespaces in it. One whitespace at the end of this line
----+
ajdustedString:
+----
Line 2 - above line is empty without spaces
Line 3 - next is empty without whitespaces
Line 5 - next line is with whitespaces
Line 7 - next 2 lines are "empty". First one with whitespaces.
Line 10 - 3 empty lines follow. The 2nd one with whitespaces in it. One whitespace at the end of this line |EOS
----+
Если вы хотите узнать больше о lookahead / lookbehind, см. Regex Tutorial - Lookahead и Lookbehind Утверждения нулевой длины: