Java, jak zastąpić 2 lub więcej spacji pojedynczym odstępem w łańcuchu i usunąć początkowe i końcowe spacje


271

Szukasz szybkiego, prostego sposobu w Javie na zmianę tego ciągu

" hello     there   "

do czegoś, co wygląda tak

"hello there"

gdzie zamieniam wszystkie te spacje na jedną spację, z wyjątkiem tego, że chcę, aby jedna lub więcej spacji na początku łańcucha zniknęła.

Coś takiego prowadzi mnie częściowo do tego

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

ale nie całkiem.


5
Powinieneś rozważyć zaakceptowanie odpowiedzi. To znacznie ułatwia osobom przybywającym na stronę później wybranie ostatecznego rozwiązania.
Paul Rooney,

1
Jest to jeden z najbardziej zalecanych sposobów. =>. Nazwa łańcuchaWithProperSpacing = StringUtils.normalizeSpace (stringWithLotOfSpaces);
Kunal Vohra

s = s.replaceAll („\\ s +”, „”);
Saroj Kumar Sahoo

Odpowiedzi:


461

Spróbuj tego:

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

Zobacz też


Brak trim()wyrażenia regularnego

Można to również zrobić za pomocą tylko jednego replaceAll, ale jest to o wiele mniej czytelne niż trim()rozwiązanie. Niemniej jednak podano tutaj, aby pokazać, co może zrobić wyrażenie regularne:

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

Istnieją 3 alternatywy:

  • ^_+ : dowolna sekwencja spacji na początku ciągu
    • Dopasuj i zamień na $1, który przechwytuje pusty ciąg
  • _+$ : dowolna sekwencja spacji na końcu ciągu
    • Dopasuj i zamień na $1, który przechwytuje pusty ciąg
  • (_)+ : dowolna sekwencja spacji, która nie pasuje do żadnego z powyższych, co oznacza, że ​​jest na środku
    • Dopasuj i zamień na $1, który przechwytuje pojedynczą spację

Zobacz też


11
+1, szczególnie, że warto zauważyć, że to robi, trim()a następnie replaceAll()zużywa mniej pamięci niż robi to na odwrót. Niewiele, ale jeśli zostanie to wywołane wiele razy, może się sumować, zwłaszcza jeśli jest wiele „przycinalnych białych znaków”. ( Trim()tak naprawdę nie pozbywa się dodatkowej przestrzeni - po prostu ukrywa ją, przesuwając wartości początkową i końcową. Podstawa char[]pozostaje niezmieniona.)
corsiKa

2
To tylko szczegół, ale myślę, że ( ) +albo ( ){2,}powinno być (bardzo) trochę bardziej wydajny;)
sp00m

6
Niezłe wyrażenie regularne. Uwaga: zastąpienie spacji `` \\szamieni dowolną grupę białych znaków na żądany znak.
djmj

1
Zauważ, że część () + dopasuje jedną spację i zastąpi ją pojedynczą spacją. Być może (<space> <space> +) byłoby lepiej, więc pasuje tylko, jeśli jest wiele spacji, a zamiana spowoduje zmianę netto łańcucha.
Lee Meador

2
Jak wspomniał Lee Meador, .trim().replaceAll(" +", " ")(z dwoma spacjami) jest szybszy niż .trim().replaceAll(" +", " ")(z jednym spacją). Przeprowadziłem testy czasowe dla ciągów, które miały tylko pojedyncze spacje i wszystkie podwójne spacje, i przyszło znacznie szybciej dla obu podczas wykonywania wielu operacji (miliony lub więcej, w zależności od środowiska).
Gary S. Weaver,

154

Potrzebujesz tylko:

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

gdzie dopasowujesz jedną lub więcej spacji i zamieniasz je na jedną spację, a następnie przycinasz białe znaki na początku i na końcu (możesz faktycznie odwrócić, najpierw przycinając, a następnie dopasowując, aby regex był szybszy, jak ktoś wskazał).

Aby to szybko przetestować, spróbuj:

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

i zwróci:

"hello there"

3
Najpierw prawdopodobnie przycinam, ponieważ wtedy oszczędzasz regexowi trochę pracy.
Michael,

3
@ sarah.ferguson Proszę usunąć ostatni wspornik „)”, którego nie powinno być w pierwszym replaceAll. Dzięki. - System nie pozwoli mi tego zrobić! (Nie mniej niż 6 znaków kwalifikuje się do edycji ..)
mwarren

2
Zauważ, że to zastępuje jedną spację inną spacją w przypadku, gdy nie ma wielu spacji razem. W takim przypadku nie ma potrzeby dokonywania zamiany, chociaż możesz tego chcieć, ponieważ zamieniasz także jedną kartę na jedną spację. Byłoby miło rozpoznać tylko wiele spacji.
Lee Meador

2
@geowar, gdzie pytanie przepraszam za pytanie? Jestem pewien, że powyższe nie zastępuje również ☮ symboli w tym przypadku .. i ani ✌ ...
sarah.ferguson

2
poczekaj sekundę @geowar Spowoduje to zastąpienie pojedynczej tabeli spacją. Właśnie próbowałem
user1870400


20

To działało idealnie dla mnie: sValue = sValue.trim().replaceAll("\\s+", " ");


1
Ludzie zredagowali moją odpowiedź. Oryginał brzmiał: sValue = sValue.replaceAll ("\ s +", "") .trim ();
Doktor

2
Został zredagowany, ponieważ twoja oryginalna odpowiedź usuwa wszystkie spacje i nie o to prosił OP
Jose Rui Santos

17
"[ ]{2,}"

Dopasuje więcej niż jedno miejsce.

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

WYNIK:

hello there

13

Aby wyeliminować spacje na początku i na końcu ciągu, użyj String#trim()metody. A następnie użyj swojego mytext.replaceAll("( )+", " ").


12

Możesz najpierw użyć String.trim(), a następnie zastosować wynik zamiany wyrażenia regularnego.


10
trim () usunie wszystkie spacje na początku i na końcu łańcucha, nie ma zastosowania do spacji między słowami
vuhung3990

10

Poniższy kod zagęści wszelkie spacje między słowami i usunie je na początku i na końcu łańcucha

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);

To wyjdzie a string with many spaces, a tab and a newline

Pamiętaj, że wszelkie znaki niedrukowalne, w tym spacje, tabulatory i znaki nowej linii, zostaną zagęszczone lub usunięte


Aby uzyskać więcej informacji, zobacz odpowiednią dokumentację:


9

Spróbuj tego.

Przykładowy kod

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

WYNIK

hello there

Najpierw zastąpi wszystkie spacje pojedynczym spacją. Następnie musimy wykonać przycinanie, Stringponieważ Początek Stringi Koniec Stringtego zastąpi całą przestrzeń pojedynczym miejscem, jeśli Stringma spacje na początku Stringi na końcu StringWięc musimy je przyciąć. Niż dostajesz swoje upragnione String.


4

Możesz także użyć lookaroundów.

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

LUB

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

<space>(?= )dopasowuje znak spacji, po którym następuje inny znak spacji. Tak więc w kolejnych spacjach pasowałby do wszystkich spacji oprócz ostatniego, ponieważ nie następuje po nim spacja. To pozostawia ci jedną spację dla kolejnych spacji po operacji usuwania.

Przykład:

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

Sposób, w jaki go masz, będzie pasował do dowolnego miejsca z przodu lub końca lub dowolnego pojedynczego miejsca z innym miejscem po nim. Oznacza to, że „a .... b” dopasuje 3 razy i zastąpi trzy razy. Iteruje po wszystkich wewnętrznych przestrzeniach w metodzie replaceAll (). Być może możesz to zmienić, aby dopasować do dowolnej sekwencji 2 lub więcej spacji jednocześnie i zmniejszyć wewnętrzną iterację.
Lee Meador,

Może <space> + (? = <space>) by to zrobił.
Lee Meador

4

trym()

Usuwa tylko spacje wiodące i końcowe.

Z Java Doc: „Zwraca ciąg, którego wartością jest ten ciąg, z usuniętymi początkowymi i końcowymi spacjami”.

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

„D ev Dum my”

replace (), replaceAll ()

Zastępuje wszystkie puste ciągi w słowie,

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+",""));

Wynik:

"DevDummy"

"DevDummy"

"DevDummy"

Uwaga: „\ s +” jest wyrażeniem regularnym podobnym do znaku pustej spacji.

Odniesienie: https://www.codedjava.com/2018/06/replace-all-spaces-in-string-trim.html


4

Jak dotąd podano wiele poprawnych odpowiedzi i widzę wiele pozytywnych opinii. Wymienione sposoby będą jednak działać, ale nie do końca zoptymalizowane lub nieczytelne. Ostatnio natknąłem się na rozwiązanie, które spodoba się każdemu deweloperowi.

String nameWithProperSpacing = StringUtils.normalizeSpace( stringWithLotOfSpaces );

Gotowe. To jest czytelne rozwiązanie.


3

W Kotlinie wyglądałoby to tak

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

2
String str = " hello world"

najpierw zmniejsz spacje

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

wielką literą pierwszą literę i wielkie litery, wszystko inne

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

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

Odpowiedzi zawierające tylko kod są odradzane. Kliknij edytuj i dodaj kilka słów podsumowujących, w jaki sposób Twój kod odpowiada na pytanie, lub może wyjaśnij, w jaki sposób Twoja odpowiedź różni się od poprzednich odpowiedzi. Dzięki
Nick

1

To zadziałało dla mnie

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

gdzie filtr podąża za funkcją, a skan jest łańcuchem wejściowym:

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
Spowodowałoby to zastąpienie <Spacja> <tab> spacją, ale nie <tab> <tab>. Wygląda na to, że to niewielki problem.
Lee Meador,

1

powinieneś to zrobić w ten sposób

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

umieść + wewnątrz okrągłych nawiasów.


1
String str = "  this is string   ";
str = str.replaceAll("\\s+", " ").trim();

0

Widzieć String.replaceAll .

Użyj wyrażenia regularnego "\s"i zamień na" " .

Następnie użyj String.trim.


1
nowy ciąg („hello there”) .replaceAll („\\ s”, „+”) zwraca + hello +++++++ tam +++, więc zdecydowanie nie działa ..
sarah.ferguson

1
Spróbujnew String(" hello there ").trim().replaceAll("\\s+", " ")
manish_s

0

Sprawdź to...

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+", "")));

} 

Jeśli String zawiera tylko pojedyncze spacje, replace () nie zastąpi,

Jeśli spacje są więcej niż jeden, wówczas akcja replace () wykonuje i usuwa spację.

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

Aby policzyć liczbę spacji w ciągu.

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;
}

Wzorzec .quote („?”) Zwraca dosłowny wzorzec String.


0

Moja metoda, zanim znalazłem drugą odpowiedź, używając wyrażenia regularnego jako lepszego rozwiązania. Może ktoś potrzebuje tego kodu.

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();
}

Ciekawe, ale biała przestrzeń oznacza więcej niż puste pola.
Laur Ivan

@LaurIvan co masz na myśli?
trinity420

ten wpis zawiera dobre wyjaśnienie tego, co \soznacza wyrażenie regularne (spacja, tabulator, nowa linia, wysuw formularza).
Laur Ivan

@LaurIvan Twój link jest uszkodzony, ale masz rację. Ten problem można rozwiązać, powtarzając ciąg wejściowy, usuwając, jak sądzę, wszystkie znaki niealfabetyczne, nienumeryczne i spacji.
trinity420

0

Wersja strumienia, filtry spacji i tabulatorów.

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

Najprostsza metoda usuwania białych znaków w dowolnym miejscu ciągu.

 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;
        }
    }
}

Powyższe rozwiązanie jest algorytmem o złożoności O (n) bez użycia jakiejkolwiek funkcji Java.


-1

Proszę użyć poniższego kodu

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

Cześć przepraszam za opóźnienie! Oto najlepsza i najbardziej efektywna odpowiedź, której szukasz:

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, " "));
}

Więc twój wynik w tym przykładzie będzie: Nazywam się Kingkon.

Jednak ta metoda usunie również „\ n”, który może mieć Twój ciąg. Więc jeśli nie chcesz, skorzystaj z tej prostej metody:

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

A jeśli chcesz też usunąć spacje wiodące i końcowe, po prostu dodaj:

str = str.trim();

-1

Wiem, że metoda replaceAll jest znacznie łatwiejsza, ale chciałem to również opublikować.

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
Chociaż to działa, nie jest to najłatwiejsze rozwiązanie.
platzhersh

-1

String Tokenizer może być używany

 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());
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.