Як видалити повторювані пробіли у рядку за допомогою Java?


147

Як видалити повторювані пробіли білого кольору (включаючи вкладки, нові рядки, пробіли тощо) у рядку за допомогою Java?

Відповіді:


378

Подобається це:

yourString = yourString.replaceAll("\\s+", " ");

Наприклад

System.out.println("lorem  ipsum   dolor \n sit.".replaceAll("\\s+", " "));

виходи

lorem ipsum dolor sit.

Що це \s+означає?

\s+є регулярним виразом. \sвідповідає пробілу, вкладці, новому рядку, поверненню каретки, стрічці форми або вертикальній вкладці і +говорить "одна або декілька з них". Таким чином, вищевказаний код згортає всі "підрядки пробілу" довше одного символу, з одним символом пробілу.


Джерело: Java: Видалення повторюваних пробілів у рядках


3
@SuhrobSamiev - String.replaceAll () працює на Java з JDK 1.4. docs.oracle.com/javase/1.4.2/docs/api/java/lang/… , java.lang.String)
Девід Молес

3
Я хотів би додати більше +1 для дивовижного пояснення \ s +.
Синтех

Я зрозумів, \s+але що означає 2 зворотні риски \\?
саджанецьPro

2
Літеральний рядок "\\"являє собою рядок, що складається з одного зворотного косого кута. Тож представляти \s+ви пишете "\\s+".
aioobe

1
Чи видалить цей вагон повернення? чи мені доведеться видаляти "\\ r" окремо? Дякую!
користувач3388884

24

Можна використовувати регулярний вираз

(\s)\1

і

замінити його на $1.

Код Java:

str = str.replaceAll("(\\s)\\1","$1");

Якщо вхід є, "foo\t\tbar "ви отримаєте "foo\tbar "як вихід,
але якщо він є, "foo\t bar"він залишиться незмінним, оскільки не має послідовних символів пробілу.

Якщо ви розглядаєте всі символи пробілу (пробіл, вертикальна вкладка, горизонтальна вкладка, повернення каретки, канал форми, новий рядок) як простір, ви можете використовувати наступний регулярний вимір для заміни будь-якої кількості послідовних пробілів на один пробіл:

str = str.replaceAll("\\s+"," ");

Але якщо ви хочете замінити два послідовних пробіли на один простір, вам слід зробити:

str = str.replaceAll("\\s{2}"," ");

9

Спробуйте це - Ви повинні import java.util.regex.*;

    Pattern pattern = Pattern.compile("\\s+");
    Matcher matcher = pattern.matcher(string);
    boolean check = matcher.find();
    String str = matcher.replaceAll(" ");

Де stringваша рядок, з якої потрібно видалити повторювані пробіли


9

привіт найшвидший (але не найкрасивіший спосіб), який я знайшов

while (cleantext.indexOf("  ") != -1)
  cleantext = StringUtils.replace(cleantext, "  ", " ");

це працює досить швидко на андроїд, навпроти регулярного виразка


1
Працює лише для пробілів, але не для інших пробілів, таких як вкладки та нові рядки.
Панг

1
я знаю, вам доведеться додати більше таких, а циклів для інших об'єктів. Але цей код працює набагато швидше на андроїд, оскільки ці регекси, мені довелося обробляти цілі електронні книги.
wutzebaer

Надзвичайно швидше і на робочому столі. Не перевіряли його на велику струну, але якщо ви плануєте виконувати її на безлічі невеликих рядків, це відповідь, яку ви шукаєте.
Ivelate

9
String str = "   Text    with    multiple    spaces    ";
str = org.apache.commons.lang3.StringUtils.normalizeSpace(str);
// str = "Text with multiple spaces"

6

Хоча вже пізно, я знайшов краще рішення (яке працює для мене), яке замінить усі послідовні білі простори одного типу одним білим простором цього типу. Це є:

   Hello!\n\n\nMy    World  

буде

 Hello!\nMy World 

Зауважте, що все ще є провідні білі проміжки. Тож моє повне рішення:

str = str.trim().replaceAll("(\\s)+", "$1"));

Тут trim()замінюються всі провідні та кінцеві рядки пробілу на "". (\\s)призначений для захоплення \\s(тобто пробілів, таких як '', '\ n', '\ t') у групі №1 . +знак призначений для відповідності 1 або більше попередніх маркерів. Так (\\s)+можуть бути послідовними символи (1 або більше) серед будь-яких окремих символів пробілу ('', '\ n' або '\ t'). $1призначений для заміни відповідних рядків рядком групи №1 (який містить лише 1 символ пробілу) відповідного типу (тобто єдиний символ пробілу, який зістав). Наведене вище рішення зміниться так:

   Hello!\n\n\nMy    World  

буде

Hello!\nMy World

Я не знайшов тут свого вище рішення, тому я його опублікував.


0

Якщо ви хочете позбутися від усіх провідних та заглиблених сторонніх пробілів, тоді ви хочете зробити щось подібне:

// \\A = Start of input boundary
// \\z = End of input boundary 
string = string.replaceAll("\\A\\s+(.*?)\\s+\\z", "$1");

Потім ви можете видалити дублікати за допомогою інших перерахованих тут стратегій:

string = string.replaceAll("\\s+"," ");

0

Ви також можете спробувати використовувати String Tokeniser для будь-якого простору, вкладок, нової лінії та всіх. Простий спосіб -

String s = "Your Text Here";        
StringTokenizer st = new StringTokenizer( s, " " );
while(st.hasMoreTokens())
{
    System.out.print(st.nextToken());
}

-10

Це можливо в три етапи:

  1. Перетворити рядок в масив символів (ToCharArray)
  2. Застосувати петлю на масиві charater
  3. Потім застосуйте функцію заміни рядків (Замінити ("жало, яке ви хочете замінити", "початковий рядок"));

1
Це не гарне рішення, перехід на масив char нічого не вирішує. Ви насправді не пояснюєте, як зробити заміну, яка є сутністю проблеми. Також, будь ласка , не публікуйте повністю незв'язані посилання. Ви позначені як спамер, якщо це зробите.
Мат
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.