Java, wie Sie zwei oder mehr Leerzeichen durch ein einzelnes Leerzeichen in einer Zeichenfolge ersetzen und führende und nachfolgende Leerzeichen löschen

271

Suchen Sie nach einer schnellen und einfachen Möglichkeit in Java, diese Zeichenfolge zu ändern

" hello     there   "

zu etwas, das so aussieht

"hello there"

Dabei ersetze ich alle diese mehreren Leerzeichen durch ein einzelnes Leerzeichen, außer ich möchte auch, dass das eine oder die mehreren Leerzeichen am Anfang der Zeichenfolge weg sind.

So etwas bringt mich teilweise dorthin

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

aber nicht ganz.

Nessa
quelle
5
Sie sollten in Betracht ziehen, eine Antwort zu akzeptieren. Dies erleichtert es Personen, die später auf die Seite gelangen, erheblich, eine endgültige Lösung zu wählen.
Paul Rooney
1
Dies ist einer der am meisten empfohlenen Wege. =>. String nameWithProperSpacing = StringUtils.normalizeSpace (stringWithLotOfSpaces);
Kunal Vohra
s = s.replaceAll ("\\ s +", "");
Saroj Kumar Sahoo

Antworten:

459

Versuche dies:

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

Siehe auch


Kein trim()Regex

Es ist auch möglich, dies mit nur einem zu tun replaceAll, aber dies ist viel weniger lesbar als die trim()Lösung. Trotzdem wird hier nur gezeigt, was Regex kann:

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

Es gibt 3 Alternativen:

  • ^_+ : eine beliebige Folge von Leerzeichen am Anfang der Zeichenfolge
    • Übereinstimmen und ersetzen mit $1, wodurch die leere Zeichenfolge erfasst wird
  • _+$ : eine beliebige Folge von Leerzeichen am Ende der Zeichenfolge
    • Übereinstimmen und ersetzen mit $1, wodurch die leere Zeichenfolge erfasst wird
  • (_)+ : Jede Folge von Leerzeichen, die mit keinem der oben genannten übereinstimmt, dh in der Mitte
    • Übereinstimmen und ersetzen mit $1, wodurch ein einzelnes Leerzeichen erfasst wird

Siehe auch

Polygenschmierstoffe
quelle
11
+1, zumal es erwähnenswert ist, dass dies geschieht trim()und dann replaceAll()weniger Speicher benötigt als umgekehrt. Nicht viel, aber wenn dies viele Male aufgerufen wird, kann es sich summieren, besonders wenn es viele "trimmbare Leerzeichen" gibt. ( Trim()Der zusätzliche Speicherplatz wird nicht wirklich entfernt - er wird nur durch Verschieben der Start- und Endwerte char[]
ausgeblendet
2
Es ist nur ein Detail, aber ich denke, dass ( ) +oder ( ){2,}sollte ein (sehr) wenig effizienter sein;)
sp00m
6
Netter regulärer Ausdruck. Hinweis: Wenn Sie das Leerzeichen `` durch \\sersetzen, wird jede Gruppe von Leerzeichen durch das gewünschte Zeichen ersetzt.
DJJJ
1
Beachten Sie, dass der Teil () + einem einzelnen Leerzeichen entspricht und durch ein einzelnes Leerzeichen ersetzt wird. Vielleicht wäre (<Leerzeichen> <Leerzeichen> +) besser, sodass es nur übereinstimmt, wenn mehrere Leerzeichen vorhanden sind und die Ersetzung eine Nettoänderung an der Zeichenfolge bewirkt.
Lee Meador
1
Wie Lee Meador erwähnte, ist .trim().replaceAll(" +", " ")(mit zwei Leerzeichen) schneller als .trim().replaceAll(" +", " ")(mit einem Leerzeichen). Ich habe Timing-Tests für Zeichenfolgen durchgeführt, die nur einfache und alle doppelten Leerzeichen enthielten, und es kam für beide wesentlich schneller, wenn viele Operationen ausgeführt wurden (Millionen oder mehr, abhängig von der Umgebung).
Gary S. Weaver
154

Sie brauchen nur ein:

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

Hier passen Sie ein oder mehrere Leerzeichen an und ersetzen sie durch ein einzelnes Leerzeichen. Schneiden Sie dann die Leerzeichen am Anfang und am Ende ab (Sie können sie tatsächlich umkehren, indem Sie sie zuerst zuschneiden und dann anpassen, um die Regex schneller zu machen, wie jemand betont hat).

Um dies schnell zu testen, versuchen Sie:

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

und es wird zurückkehren:

"hello there"
sarah.ferguson
quelle
3
Ich würde wahrscheinlich zuerst schneiden, weil Sie dann dem regulären Ausdruck ein wenig Arbeit ersparen.
Michael
3
@ sarah.ferguson Bitte entfernen Sie die letzte Klammer ")", die beim ersten Ersetzen nicht vorhanden sein sollte. Vielen Dank. - Das System würde mich das nicht machen lassen! (
Nicht
2
Beachten Sie, dass dies ein Leerzeichen durch ein anderes ersetzt, wenn nicht mehrere Leerzeichen zusammen vorhanden sind. In diesem Fall ist das Ersetzen nicht erforderlich, obwohl Sie dies möglicherweise möchten, da Sie auch eine Registerkarte durch ein einzelnes Leerzeichen ersetzen. Es wäre schön, nur mehrere Leerzeichen zu erkennen.
Lee Meador
2
@geowar wo hat die frage nach tabs gefragt sorry? Ich bin sicher, dass die oben genannten nicht auch ☮ Symbole für diese Angelegenheit ersetzen .. und auch nicht ✌ ...
sarah.ferguson
2
warte eine Sekunde @geowar Dies ersetzt eine einzelne Tabelle durch ein Leerzeichen. Ich habe es gerade versucht
user1870400
42

Verwenden Sie die Apache Commons- StringUtils.normalizeSpace(String str)Methode. Siehe Dokumente hier

Monica Granbois
quelle
Gute Idee, aber dies entfernt unter anderem
Zeilenumbrüche
20

Das hat bei mir perfekt funktioniert: sValue = sValue.trim().replaceAll("\\s+", " ");

Arzt
quelle
1
Die Leute haben meine Antwort bearbeitet. Das Original war: sValue = sValue.replaceAll ("\ s +", "") .trim ();
Doktor
2
Wurde bearbeitet, weil Ihre ursprüngliche Antwort alle Leerzeichen entfernt und das OP nicht darum gebeten hat
Jose Rui Santos
17
"[ ]{2,}"

Dies entspricht mehr als einem Leerzeichen.

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

AUSGABE:

hello there
Gitesh Dalal
quelle
13

Verwenden Sie die String#trim()Methode, um Leerzeichen am Anfang und am Ende des Strings zu entfernen. Und dann benutze deine mytext.replaceAll("( )+", " ").

Folone
quelle
12

Sie können String.trim()den Befehl regex replace zuerst verwenden und dann auf das Ergebnis anwenden.

Eyal Schneider
quelle
10
trim () entfernt das gesamte Leerzeichen am Anfang und Ende der Zeichenfolge. Es gilt nicht für Leerzeichen zwischen Wörtern
vuhung3990
10

Der folgende Code komprimiert Leerzeichen zwischen Wörtern und entfernt Leerzeichen am Anfang und Ende der Zeichenfolge

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

Dies wird ausgegeben a string with many spaces, a tab and a newline

Beachten Sie, dass nicht druckbare Zeichen, einschließlich Leerzeichen, Tabulatoren und Zeilenumbrüche, komprimiert oder entfernt werden


Weitere Informationen finden Sie in der jeweiligen Dokumentation:

xcuipir
quelle
9

Probier diese.

Beispielcode

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

AUSGABE

hello there

Zuerst werden alle Leerzeichen durch ein einzelnes Leerzeichen ersetzt. Dann müssen wir das Trimmen durchführen, Stringda der Beginn des Stringund des Endes Stringden gesamten Raum durch einen einzelnen Raum ersetzt, wenn Stringam Anfang des Stringund des Endes des Raums Leerzeichen vorhanden sind. StringWir müssen sie also trimmen. Dann bekommen Sie Ihren Wunsch String.

Raj S. Rusia
quelle
4

Sie können auch Lookarounds verwenden.

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

ODER

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

<space>(?= )Entspricht einem Leerzeichen, auf das ein weiteres Leerzeichen folgt. In aufeinanderfolgenden Leerzeichen würde es also mit allen Leerzeichen außer dem letzten übereinstimmen, da kein Leerzeichen folgt. Dadurch bleibt Ihnen nach dem Entfernungsvorgang ein einziges Leerzeichen für aufeinanderfolgende Leerzeichen.

Beispiel:

    String[] tests = {
            "  x  ",          // [x]
            "  1   2   3  ",  // [1 2 3]
            "",               // []
            "   ",            // []
        };
        for (String test : tests) {
            System.out.format("[%s]%n",
                test.replaceAll("^ +| +$| (?= )", "")
            );
        }
Avinash Raj
quelle
So wie Sie es haben, wird es jedes Feld an der Vorderseite oder am Ende oder jedes einzelne Feld mit einem anderen Feld danach abgleichen. Das bedeutet, dass "a .... b" dreimal übereinstimmt und dreimal ersetzt wird. Es iteriert über alle internen Bereiche innerhalb der replaceAll () -Methode. Vielleicht können Sie es so ändern, dass es mit einer beliebigen Folge von zwei oder mehr Leerzeichen gleichzeitig übereinstimmt, und die interne Iteration reduzieren.
Lee Meador
Vielleicht würde <space> + (? = <Space>) es tun.
Lee Meador
4

trimmen()

Entfernt nur die führenden und nachfolgenden Leerzeichen.

In Java Doc heißt es: "Gibt eine Zeichenfolge zurück, deren Wert diese Zeichenfolge ist, wobei alle führenden und nachfolgenden Leerzeichen entfernt wurden."

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

"D ev Dum my"

replace (), replaceAll ()

Ersetzt alle leeren Zeichenfolgen im Wort.

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

Ausgabe:

"DevDummy"

"DevDummy"

"DevDummy"

Hinweis: "\ s +" ist der reguläre Ausdruck, der dem Leerzeichen ähnelt.

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

Sameera
quelle
4

Bisher wurden viele richtige Antworten gegeben, und ich sehe viele positive Stimmen. Die genannten Methoden funktionieren jedoch, sind jedoch nicht wirklich optimiert oder nicht wirklich lesbar. Ich bin kürzlich auf die Lösung gestoßen, die jedem Entwickler gefallen wird.

String nameWithProperSpacing = StringUtils.normalizeSpace( stringWithLotOfSpaces );

Du bist fertig. Dies ist eine lesbare Lösung.

Kunal Vohra
quelle
3

In Kotlin würde es so aussehen

val input = "\n\n\n  a     string with     many    spaces,    \n"
val cleanedInput = input.trim().replace(Regex("(\\s)+"), " ")
Rafael
quelle
2
String str = " hello world"

Leerzeichen zuerst reduzieren

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

Großschreibung des ersten Buchstabens und Kleinbuchstaben alles andere

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

Das hat bei mir funktioniert

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

Dabei folgt der Filter der Funktion und der Scan die Eingabezeichenfolge:

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();
}
Mr_Hmp
quelle
1
Dies würde <Leerzeichen> <Tab> durch ein Leerzeichen ersetzen, jedoch nicht <Tab> <Tab>. Das ist anscheinend ein kleines Problem.
Lee Meador
1

du solltest es so machen

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

+ in runde Klammern setzen.

kiro malak
quelle
1
String str = "  this is string   ";
str = str.replaceAll("\\s+", " ").trim();
Ajinkya_M
quelle
1
mytext = mytext.replaceAll("\\s+"," ");
k sarath
quelle
Von Nur-Code-Antworten wird abgeraten. Klicken Sie auf Bearbeiten und fügen Sie einige Wörter hinzu, die zusammenfassen, wie Ihr Code die Frage beantwortet, oder erklären Sie möglicherweise, wie sich Ihre Antwort von den vorherigen Antworten unterscheidet. Danke
Nick
0

Siehe String.replaceAll.

Verwenden Sie den regulären Ausdruck "\s"und ersetzen Sie ihn durch " ".

Dann verwenden String.trim.

Zak
quelle
1
neuer String ("Hallo da") .replaceAll ("\\ s", "+") gibt ein + Hallo +++++++ dort +++ zurück, funktioniert also definitiv nicht ..
sarah.ferguson
1
Trynew String(" hello there ").trim().replaceAll("\\s+", " ")
manish_s
0

Überprüfen Sie dies...

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

} 

Wenn String nur ein Leerzeichen enthält, wird replace () nicht ersetzt.

Wenn Leerzeichen mehr als eins sind, führt die Aktion replace () die Leerzeichen aus und entfernt sie.

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

Zählen der Anzahl der Leerzeichen in einem String.

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

Pattern .quote ("?") Gibt das Literalmuster String zurück.

Yash
quelle
0

Meine Methode, bevor ich die zweite Antwort mit Regex als bessere Lösung fand. Vielleicht braucht jemand diesen Code.

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();
}
trinity420
quelle
Interessant, aber Leerraum bedeutet mehr als nur Leerzeichen.
Laur Ivan
@LaurIvan was meinst du?
Trinity420
Dieser Eintrag enthält eine gute Erklärung dafür, wofür \sreguläre Ausdrücke stehen (Leerzeichen, Tabulator, neue Zeile, Formular-Feed).
Laur Ivan
@LaurIvan Dein Link ist kaputt, aber du hast recht. Dieses Problem könnte gelöst werden, indem die Eingabezeichenfolge durchlaufen wird und jedes nicht alphabetische, nicht numerische und nicht Leerzeichen entfernt wird, denke ich.
Trinity420
0

Stream-Version, filtert Leerzeichen und Tabulatoren.

Stream.of(str.split("[ \\t]")).filter(s -> s.length() > 0).collect(Collectors.joining(" "))
Aris2World
quelle
0
String myText = "   Hello     World   ";
myText = myText.trim().replace(/ +(?= )/g,'');


// Output: "Hello World"
alaswer
quelle
0

Die einfachste Methode zum Entfernen von Leerzeichen an einer beliebigen Stelle in der Zeichenfolge.

 public String removeWhiteSpaces(String returnString){
    returnString = returnString.trim().replaceAll("^ +| +$|( )+", " ");
    return returnString;
}
Sandun Susantha
quelle
-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;
        }
    }
}

Die obige Lösung ist der Algorithmus mit der Komplexität von O (n) ohne Verwendung einer Java-Funktion.

devmohd
quelle
-1

Bitte verwenden Sie den folgenden Code

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

Hallo Entschuldigung für die Verzögerung! Hier ist die beste und effizienteste Antwort, die Sie suchen:

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

Ihre Ausgabe dieses Beispiels lautet also: Mein Name ist kingkon.

Diese Methode entfernt jedoch auch das "\ n", das Ihre Zeichenfolge möglicherweise hat. Wenn Sie das nicht möchten, verwenden Sie einfach diese einfache Methode:

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

Und wenn Sie auch die führenden und nachfolgenden Leerzeichen entfernen möchten, fügen Sie einfach Folgendes hinzu:

str = str.trim();
kostas poimenidhs
quelle
-1

Ich weiß, dass die replaceAll-Methode viel einfacher ist, aber ich wollte dies auch posten.

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;
}
Esranur
quelle
1
Obwohl dies funktioniert, ist es bei weitem nicht die einfachste Lösung.
Platzhersh
-1

String Tokenizer kann verwendet werden

 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());
Swaran
quelle