Java, як замінити 2 або більше пробілів одним пробілом у рядку та видалити провідні та кінцеві пробіли


271

Шукаєте швидкий, простий спосіб змінити цей рядок у Java

" hello     there   "

до чогось, що виглядає так

"hello there"

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

Щось подібне мене частково отримує там

String mytext = " hello     there   ";
mytext = mytext.replaceAll("( )+", " ");

але не зовсім.


5
Слід розглянути можливість прийняття відповіді. Людям, які приїжджають на сторінку, набагато простіше вибрати остаточне рішення.
Пол Руні

1
Це один із найбільш рекомендованих способів. =>. Ім'я рядкаWithProperSpacing = StringUtils.normalizeSpace (stringWithLotOfSpaces);
Kunal

s = s.replaceAll ("\\ s +", "");
Сарой Кумар Саху

Відповіді:


461

Спробуйте це:

String after = before.trim().replaceAll(" +", " ");

Дивитися також


Без trim()регексу

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

    String[] tests = {
        "  x  ",          // [x]
        "  1   2   3  ",  // [1 2 3]
        "",               // []
        "   ",            // []
    };
    for (String test : tests) {
        System.out.format("[%s]%n",
            test.replaceAll("^ +| +$|( )+", "$1")
        );
    }

Є 3 альтернативи:

  • ^_+ : будь-яка послідовність пробілів на початку рядка
    • Збіг і заміни на $1, що фіксує порожній рядок
  • _+$ : будь-яка послідовність пробілів в кінці рядка
    • Збіг і заміни на $1, що фіксує порожній рядок
  • (_)+ : будь-яка послідовність пробілів, яка не відповідає жодному з вищезазначених, тобто це посередині
    • Збіг і заміни на $1, що фіксує єдиний пробіл

Дивитися також


11
+1, тим більше, що варто відзначити, що робити, trim()а потім replaceAll()використовує менше пам'яті, ніж робити це навпаки. Не на багато, але якщо це називається багато разів, це може скластися, особливо якщо багато "прорізувальної пробілу". ( Trim()насправді не позбавляється від зайвого простору - він просто приховує його, переміщуючи початкові та кінцеві значення. Основне char[]залишається незмінним.)
corsiKa

2
Це всього лише деталь, але я думаю , що ( ) +і ( ){2,}повинно бути (дуже) трохи більш ефективним;)
sp00m

6
Гарний регепс. Примітка: заміна простору `` на ' \\sзамінить будь-яку групу пробілів потрібним символом.
djmj

1
Зауважте, що () + частина збігатиметься з одним пробілом і замінить його на один пробіл. Можливо (<space> <space> +) було б краще, тому він збігається лише за наявності кількох пробілів і заміна внесе чисту зміну в рядок.
Лі Меадор

2
Як згадував Лі Меадор, .trim().replaceAll(" +", " ")(з двома пробілами) швидше, ніж .trim().replaceAll(" +", " ")(з одним пробілом). Я провів тести синхронізації на рядках , які мали тільки окремі прогалини і все подвійні пробіли, і він прийшов в істотно швидше і при виконанні багато операцій (мільйони або більше, в залежності від навколишнього середовища).
Гері С. Вівер

154

Вам просто потрібно:

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

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

Щоб швидко перевірити це, спробуйте:

System.out.println(new String(" hello     there   ").trim().replaceAll("\\s{2,}", " "));

і воно повернеться:

"hello there"

3
Я, мабуть, спершу обрізаю, тому що потім ви збережете регекс трохи роботи.
Майкл

3
@ sarah.ferguson Видаліть остаточну дужку ")", яка не повинна бути там у першій заміні. Всі. Дякую. - Система не дозволила мені це зробити! (Нічого менше 6 символів придатне для редагування ..)
mwarren

2
Зауважте, що це замінює один простір іншим, якщо немає кількох пробілів разом. У цьому випадку не потрібно робити заміну, хоча ви, можливо, захочете, оскільки ви також замінюєте одну вкладку одним простором. Було б непогано розпізнавати лише декілька пробілів.
Лі Медор

2
@geowar, де питання запитали вкладки вибачте? Я впевнений, що зазначене вище не замінює ☮ символи з цього питання .. і ні and ...
sarah.ferguson

2
зачекайте другий @geowar Це замінює одну таблицю пробілом. Я щойно спробував це
user1870400


20

Це прекрасно працювало для мене: sValue = sValue.trim().replaceAll("\\s+", " ");


1
Люди редагували мою відповідь. Оригінал був: sValue = sValue.replaceAll ("\ s +", "") .trim ();
Лікар

2
Був відредагований тому, що ваша оригінальна відповідь видаляє всі пробіли, і це не те, що запитувала ОП
Хосе Руй Сантос

17
"[ ]{2,}"

Це буде відповідати більш ніж одному пробілу.

String mytext = " hello     there   ";
//without trim -> " hello there"
//with trim -> "hello there"
mytext = mytext.trim().replaceAll("[ ]{2,}", " ");
System.out.println(mytext);

ВИХІД:

hello there

13

Для усунення пробілів на початку та в кінці рядка використовуйте String#trim()метод. А потім скористайтеся своїм mytext.replaceAll("( )+", " ").


12

Ви можете спочатку використовувати String.trim(), а потім застосувати команду заміни регулярних виразів на результат.


10
trim () видалить увесь пробіл на початку та в кінці рядка, це не застосовується для пробілу між словами
vuhung3990

10

Наступний код дозволить ущільнити пробіл між словами та видалити будь-який на початку та в кінці рядка

String input = "\n\n\n  a     string with     many    spaces,    \n"+
               " a \t tab and a newline\n\n";
String output = input.trim().replaceAll("\\s+", " ");
System.out.println(output);

Це виведе a string with many spaces, a tab and a newline

Зауважте, що будь-які символи, що не надрукуються, включаючи пробіли, вкладки та нові рядки, будуть ущільнені або видалені


Для отримання додаткової інформації див відповідну документацію:


9

Спробуйте це.

Зразок коду

String str = " hello     there   ";
System.out.println(str.replaceAll("( +)"," ").trim());

ВИХІД

hello there

По-перше, він замінить усі простори одним простором. Тож, як нам належить зробити обрізки, Stringтому що Початок Stringі Кінець цього місця Stringзамінить весь простір на один простір, якщо у ньому Stringє пробіли на початку Stringта в кінці, Stringтому нам потрібно їх обрізати. Чим ви отримаєте своє бажане String.


4

Ви також можете використовувати lookarounds.

test.replaceAll("^ +| +$|(?<= ) ", "");

АБО

test.replaceAll("^ +| +$| (?= )", "")

<space>(?= )відповідає символу пробілу, за яким слідує інший пробільний символ. Таким чином, у послідовних пробілах воно буде відповідати всім пробілам, окрім останнього, тому що за ним не йде символ пробілу. Це залишає вам єдиний простір для послідовних пробілів після операції видалення.

Приклад:

    String[] tests = {
            "  x  ",          // [x]
            "  1   2   3  ",  // [1 2 3]
            "",               // []
            "   ",            // []
        };
        for (String test : tests) {
            System.out.format("[%s]%n",
                test.replaceAll("^ +| +$| (?= )", "")
            );
        }

Як ви маєте його, він буде відповідати будь-якому простору на передній або кінці або будь-якому одному просторі з іншим пробілом після нього. Це означає, що "a .... b" буде відповідати 3 рази та заміняти три рази. Він повторює всі внутрішні простори всередині методу substituAll (). Можливо, ви могли б змінити його так, щоб відповідати будь-якій послідовності з двох або більше пробілів відразу і зменшити внутрішню ітерацію.
Лі Медор

Можливо, <space> + (? = <Простір>) зробив би це.
Лі Меадор

4

обрізка ()

Вилучає лише провідні та кінцеві місця.

З Java Doc "Повертає рядок, значенням якої є ця рядок, з будь-яким провідним і заднім пробілом видалено".

System.out.println(" D ev  Dum my ".trim());

"D ev Dum my"

заміна (), замінаВсі ()

Замінює всі порожні рядки в слові,

System.out.println(" D ev  Dum my ".replace(" ",""));

System.out.println(" D ev  Dum my ".replaceAll(" ",""));

System.out.println(" D ev  Dum my ".replaceAll("\\s+",""));

Вихід:

"DevDummy"

"DevDummy"

"DevDummy"

Примітка: "\ s +" - це регулярний вираз, подібний до символу порожнього простору.

Довідка: https://www.codedjava.com/2018/06/replace-all-spaces-in-string-trim.html


4

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

String nameWithProperSpacing = StringUtils.normalizeSpace( stringWithLotOfSpaces );

Ви закінчили. Це читабельне рішення.


3

У Котліні це виглядало б так

val input = "\n\n\n  a     string with     many    spaces,    \n"
val cleanedInput = input.trim().replace(Regex("(\\s)+"), " ")

2
String str = " hello world"

спочатку зменшіть пробіли

str = str.trim().replaceAll(" +", " ");

з великої літери напишіть з малої літери та з малого решти всього іншого

str = str.substring(0,1).toUpperCase() +str.substring(1,str.length()).toLowerCase();

2
mytext = mytext.replaceAll("\\s+"," ");

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

1

Це працювало для мене

scan= filter(scan, " [\\s]+", " ");
scan= sac.trim();

де фільтр виконує наступні функції, а сканування - вхідний рядок:

public String filter(String scan, String regex, String replace) {
    StringBuffer sb = new StringBuffer();

    Pattern pt = Pattern.compile(regex);
    Matcher m = pt.matcher(scan);

    while (m.find()) {
        m.appendReplacement(sb, replace);
    }

    m.appendTail(sb);

    return sb.toString();
}

1
Це замінить <space> <tab> пробілом, але не <tab> <tab>. Це, мабуть, незначна проблема.
Лі Меадор

1

ви повинні робити це так

String mytext = " hello     there   ";
mytext = mytext.replaceAll("( +)", " ");

поставити + всередині круглі дужки.



0

Див String.replaceAll.

Використовуйте регулярний вираз "\s"і замініть його " ".

Потім використовуйте String.trim.


1
new String ("привіт там") .replaceAll ("\\ s", "+") повертає + hello +++++++ там +++, так що точно не працює ..
sarah.ferguson

1
Спробуйтеnew String(" hello there ").trim().replaceAll("\\s+", " ")
manish_s

0

Перевір це...

public static void main(String[] args) {
    String s = "A B  C   D    E F      G\tH I\rJ\nK\tL";
    System.out.println("Current      : "+s);
    System.out.println("Single Space : "+singleSpace(s));
    System.out.println("Space  count : "+spaceCount(s));
    System.out.format("Replace  all = %s", s.replaceAll("\\s+", ""));

    // Example where it uses the most.
    String s = "My name is yashwanth . M";
    String s2 = "My nameis yashwanth.M";

    System.out.println("Normal  : "+s.equals(s2));
    System.out.println("Replace : "+s.replaceAll("\\s+", "").equals(s2.replaceAll("\\s+", "")));

} 

Якщо рядок містить лише один пробіл, тоді заміна () не замінить,

Якщо пробілів більше, ніж один, тоді операція заміни () виконує та видаляє пробіл.

public static String singleSpace(String str){
    return str.replaceAll("  +|   +|\t|\r|\n","");
}

Для підрахунку кількості пробілів у рядку.

public static String spaceCount(String str){
    int i = 0;
    while(str.indexOf(" ") > -1){
      //str = str.replaceFirst(" ", ""+(i++));
        str = str.replaceFirst(Pattern.quote(" "), ""+(i++)); 
    }
    return str;
}

Шаблон .quote ("?") Повертає буквальний рядок шаблону.


0

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

private String replaceMultipleSpacesFromString(String s){
    if(s.length() == 0 ) return "";

    int timesSpace = 0;
    String res = "";

    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);

        if(c == ' '){
            timesSpace++;
            if(timesSpace < 2)
                res += c;
        }else{
            res += c;
            timesSpace = 0;
        }
    }

    return res.trim();
}

Цікаво, але білий простір означає більше, ніж просто заготовки.
Лаур Іван

@LaurIvan, що ти маєш на увазі?
trinity420

Цей запис дає хороше пояснення щодо того, що \sстоїть у регулярних виразах (пробіл, вкладка, новий рядок, канал форми).
Лаур Іван

@LaurIvan Ваше посилання зламане, але ви маєте рацію. Цю проблему можна було б вирішити шляхом ітерації через рядок введення, видалення кожного не алфавітного, нечислового та непробільного символів, я думаю.
trinity420

0

Версія потоку, фільтрує пробіли та вкладки.

Stream.of(str.split("[ \\t]")).filter(s -> s.length() > 0).collect(Collectors.joining(" "))

0
String myText = "   Hello     World   ";
myText = myText.trim().replace(/ +(?= )/g,'');


// Output: "Hello World"

0

Найпростіший метод видалення білого простору в будь-якому місці рядка.

 public String removeWhiteSpaces(String returnString){
    returnString = returnString.trim().replaceAll("^ +| +$|( )+", " ");
    return returnString;
}

-1
public class RemoveExtraSpacesEfficient {

    public static void main(String[] args) {

        String s = "my    name is    mr    space ";

        char[] charArray = s.toCharArray();

        char prev = s.charAt(0);

        for (int i = 0; i < charArray.length; i++) {
            char cur = charArray[i];
            if (cur == ' ' && prev == ' ') {

            } else {
                System.out.print(cur);
            }
            prev = cur;
        }
    }
}

Вищенаведене рішення - алгоритм зі складністю O (n) без використання жодної функції java.


-1

Будь ласка, використовуйте код нижче

package com.myjava.string;

import java.util.StringTokenizer;

public class MyStrRemoveMultSpaces {

    public static void main(String a[]){

        String str = "String    With Multiple      Spaces";

        StringTokenizer st = new StringTokenizer(str, " ");

        StringBuffer sb = new StringBuffer();

        while(st.hasMoreElements()){
            sb.append(st.nextElement()).append(" ");
        }

        System.out.println(sb.toString().trim());
    }
}

-1

Привіт пробачте за затримку! Ось найкраща та найефективніша відповідь, яку ви шукаєте:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyPatternReplace {

public String replaceWithPattern(String str,String replace){

    Pattern ptn = Pattern.compile("\\s+");
    Matcher mtch = ptn.matcher(str);
    return mtch.replaceAll(replace);
}

public static void main(String a[]){
    String str = "My    name    is  kingkon.  ";
    MyPatternReplace mpr = new MyPatternReplace();
    System.out.println(mpr.replaceWithPattern(str, " "));
}

Тож ваш результат цього прикладу буде: Мене звуть kingkon.

Однак цей метод також видалить "\ n", що може мати ваша рядок. Тож якщо ви цього не хочете, просто використовуйте цей простий метод:

while (str.contains("  ")){  //2 spaces
str = str.replace("  ", " "); //(2 spaces, 1 space) 
}

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

str = str.trim();

-1

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

public static String removeExtraSpace(String input) {
    input= input.trim();
    ArrayList <String> x= new ArrayList<>(Arrays.asList(input.split("")));
    for(int i=0; i<x.size()-1;i++) {
        if(x.get(i).equals(" ") && x.get(i+1).equals(" ")) { 
            x.remove(i); 
            i--; 
        }
    }
    String word="";
    for(String each: x) 
        word+=each;
    return word;
}

1
Хоча це працює, це далеко не найпростіше рішення.
платжерш

-1

Можна використовувати струнний токенізатор

 String str = "  hello    there  ";
            StringTokenizer stknzr = new StringTokenizer(str, " ");
            StringBuffer sb = new StringBuffer();
            while(stknzr.hasMoreElements())
            {
                sb.append(stknzr.nextElement()).append(" ");
            }
            System.out.println(sb.toString().trim());
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.