Java, 2 veya daha fazla boşluğun dizedeki tek boşlukla nasıl değiştirileceği ve önde gelen ve sondaki boşlukların nasıl silineceği


271

Bu dizeyi değiştirmek için Java'da hızlı ve basit bir yol mu arıyorsunuz?

" hello     there   "

şuna benzeyen bir şeye

"hello there"

burada dizenin başlangıcındaki bir veya daha fazla boşluğun gitmesini istemiyorum hariç, tüm bu çoklu boşlukları tek bir boşlukla değiştiriyorum.

Böyle bir şey beni kısmen oraya götürüyor

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

ama tam olarak değil.


5
Bir yanıtı kabul etmeyi düşünmelisiniz. Daha sonra sayfaya ulaşan kişilerin kesin bir çözüm seçmesini kolaylaştırır.
Paul Rooney

1
Bu en çok tavsiye edilen yollardan biridir. =>. Dize nameWithProperSpacing = StringUtils.normalizeSpace (stringWithLotOfSpaces);
Kunal Vohra

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

Yanıtlar:


461

Bunu dene:

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

Ayrıca bakınız


trim()Normal ifade yok

Bunu sadece biriyle yapmak da mümkündür replaceAll, ancak bu trim()çözümden daha az okunabilir . Bununla birlikte, burada regex'in neler yapabileceğini göstermek için sağlanmıştır:

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

3 alternatif var:

  • ^_+ : dizenin başındaki herhangi bir boşluk dizisi
    • $1Boş dizeyi yakalayan ile eşleştirin ve değiştirin
  • _+$ : dizenin sonundaki herhangi bir boşluk dizisi
    • $1Boş dizeyi yakalayan ile eşleştirin ve değiştirin
  • (_)+ : Yukarıdakilerin hiçbiriyle eşleşmeyen herhangi bir boşluk dizisi, yani ortada
    • $1Tek bir alanı yakalayan ile eşleştirin ve değiştirin

Ayrıca bakınız


11
+1, özellikle bunu yapmanın dikkatini çekmeye değer trim()ve daha sonra replaceAll()bunu tersine yapmaktan daha az bellek kullanıyor. Çok fazla değil, ama bu birçok kez çağrılırsa, özellikle çok fazla "kesilebilir beyaz alan" varsa toplanabilir. ( Trim()ekstra alandan gerçekten kurtulmaz - sadece başlangıç ​​ve bitiş değerlerini hareket ettirerek gizler. Altta yatan char[]değişmeden kalır.)
corsiKa

2
Sadece bir ayrıntı, ama düşünüyorum ( ) +ya ( ){2,}bir (çok) biraz daha verimli olmalı;)
sp00m

6
Güzel regexp. Not: `` boşluğunun \\sdeğiştirilmesi, herhangi bir beyaz boşluk grubunu istenen karakterle değiştirecektir.
djmj

1
() + Parçasının tek bir boşlukla eşleşeceğini ve yerine tek bir boşluk koyacağını unutmayın. Belki (<space> <space> +) daha iyi olurdu, bu yüzden sadece birden fazla boşluk varsa ve değiştirme dizede net bir değişiklik yapacaksa eşleşir.
Lee Meador

2
Lee Meador'un da belirttiği gibi, .trim().replaceAll(" +", " ")(iki boşluklu) .trim().replaceAll(" +", " ")bir boşluktan daha hızlıdır . Sadece tek boşlukları ve tüm çift boşlukları olan dizelerde zamanlama testleri yaptım ve çok fazla işlem yaparken (ortama bağlı olarak milyonlarca veya daha fazla) her ikisi için de oldukça hızlı geldi .
Gary S. Weaver

154

Tek ihtiyacınız olan:

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

burada bir veya daha fazla boşluğu eşleştirip bunları tek bir boşlukla değiştirip daha sonra boşlukları başlangıçta ve sonunda kırpabilirsiniz (birisinin işaret ettiği gibi regex'i daha hızlı hale getirmek için ilk kırparak ve ardından eşleştirerek tersine çevirebilirsiniz).

Bunu hızlı bir şekilde test etmek için şunu deneyin:

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

ve geri dönecek:

"hello there"

3
Muhtemelen önce düzeltirim çünkü regex'i biraz işten kurtarıyorsunuz.
Michael

3
@ sarah.ferguson Lütfen ilk değiştirmede olmaması gereken son braketi ")" çıkarın. Teşekkürler. - Sistem yapmama izin vermedi! (6 karakterden daha az bir şey düzenleme için uygun değildir.)
mwarren

2
Bunun, birden fazla boşluğun olmadığı durumlarda bir boşluğun başka bir boşlukla değiştirildiğini unutmayın. Bu durumda, bir sekmeyi tek bir boşlukla değiştirdiğiniz için, değiştirmeye gerek yoktur. Yalnızca birden çok alanı tanımak iyi olur.
Lee Meador

2
@geowar soru neden sekmeleri istedi? Eminim yukarıdaki ☮ sembolleri de bu konunun yerini almaz .. ve hiçbiri ...
sarah.ferguson

2
wait second secondgeowar Tek bir tabloyu boşlukla değiştirir. Ben sadece denedim
user1870400


20

Bu benim için mükemmel çalıştı: sValue = sValue.trim().replaceAll("\\s+", " ");


1
İnsanlar cevabımı düzenledi. Orijinal şuydu: sValue = sValue.replaceAll ("\ s +", "") .trim ();
Doktor

2
Orijinal cevabınız tüm alanları kaldırdığı ve OP'nin istediği bu olmadığı için düzenlendi
Jose Rui Santos

17
"[ ]{2,}"

Bu, birden fazla alanla eşleşecektir.

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

ÇIKTI:

hello there

13

Dizenin başında ve sonundaki boşlukları ortadan kaldırmak için String#trim()yöntemi kullanın . Ve sonra kullanın mytext.replaceAll("( )+", " ").


12

Önce String.trim()regex replace komutunu kullanabilir ve ardından sonuca uygulayabilirsiniz.


10
trim (), dizenin başında ve sonunda tüm boşlukları kaldırır, kelimeler arasındaki boşluk için geçerli değildir
vuhung3990

10

Aşağıdaki kod, kelimeler arasındaki boşlukları sıkıştırır ve dizenin başında ve sonunda bunları kaldırır

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

Bu çıktı a string with many spaces, a tab and a newline

Boşluklar, sekmeler ve yeni satırlar dahil yazdırılamayan karakterlerin sıkıştırılacağını veya kaldırılacağını unutmayın


Daha fazla bilgi için ilgili belgelere bakın:


9

Bunu dene.

Basit kod

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

ÇIKTI

hello there

İlk olarak tüm boşlukları tek boşlukla değiştirecek. Biz kırpma yapmak gerekiyordu mu daha Stringçalıştırma nedeniyle Stringve End Stringeğer tek boşluk ile tüm alanı yerini alacak Stringait başlayarak boşlukları vardır Stringve sonu Stringonları kırpmak gerek Yani. Daha istediğiniz olsun String.


4

Lookaround'ları da kullanabilirsiniz.

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

VEYA

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

<space>(?= )bir boşluk karakteriyle ve ardından başka bir boşluk karakteriyle eşleşir. Birbirini izleyen uzaylarda, bir boşluk karakteri izlemediği için, son hariç tüm boşluklarla eşleşir. Bu, kaldırma işleminden sonra art arda boşluklar için size tek bir alan bırakır.

Misal:

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

Sahip olduğunuz şekilde, öndeki veya uçtaki herhangi bir alanı veya herhangi bir alanı, sonraki başka bir alanla eşleştirecektir. Bu, "a .... b" ifadesinin 3 kez eşleşeceği ve üç kez değiştirileceği anlamına gelir. ReplaceAll () yönteminin içindeki tüm iç boşlukları yineler. Belki de bir kerede 2 veya daha fazla boşluk dizisine uyacak şekilde değiştirebilir ve dahili yinelemeyi azaltabilirsiniz.
Lee Meador

Belki <space> + (? = <space>) yapardı.
Lee Meador

4

) (Döşeme

Yalnızca önde gelen ve arkadaki boşlukları kaldırır.

Java Doc'tan "Değeri bu dize olan ve önde ve arkadaki boşluklar kaldırılmış bir dize döndürür."

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

"D ev Dum my"

replace (), replaceAll ()

Kelimedeki tüm boş dizelerin yerini alır,

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

Çıktı:

"DevDummy"

"DevDummy"

"DevDummy"

Not: "\ s +", boş boşluk karakterine benzer normal ifadedir.

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


4

Şimdiye kadar çok sayıda doğru cevap verildi ve çok sayıda upvotes görüyorum. Bununla birlikte, bahsedilen yollar işe yarayacak, ancak gerçekten optimize edilmemiş veya gerçekten okunamıyor. Kısa süre önce her geliştiricinin beğeneceği bir çözümle karşılaştım.

String nameWithProperSpacing = StringUtils.normalizeSpace( stringWithLotOfSpaces );

Bitirdiniz. Bu okunabilir bir çözümdür.


3

Kotlin'de şöyle görünecekti

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

2
String str = " hello world"

önce boşlukları azalt

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

ilk harfi büyük yaz ve diğer her şeyi küçük harfe çevirme

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

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

Yalnızca kod yanıtları önerilmez. Tıklayınız düzenlemek önceki cevaplardan nasıl cevap farklılık açıklamak belki ve kod adresleri nasıl soru özetleyen bazı kelimeler ekleyebilir veya. Teşekkürler
Nick

1

Bu benim için çalıştı

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

burada filtre işlevi takip eder ve tarama giriş dizesidir:

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
Bu, <boşluk> <tab> yerine bir boşluk bırakılır ancak <tab> <tab> ile değiştirilmez. Bu küçük bir sorun gibi görünüyor.
Lee Meador

1

böyle yapmalısın

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

+ yuvarlak köşeli parantez içine koyun.


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

0

Bkz String.replaceAll.

Normal ifadeyi kullanın "\s"ve ile değiştirin " ".

Sonra kullanın String.trim.


1
yeni Dize ("merhaba orada") .replaceAll ("\\ s", "+") orada bir + merhaba +++++++ döndürür +++ bu yüzden kesinlikle çalışmıyor ..
sarah.ferguson

1
Deneyinnew String(" hello there ").trim().replaceAll("\\s+", " ")
manish_s

0

şuna göz at...

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

} 

Dize yalnızca tek boşluk içeriyorsa, replace () değişmez,

Boşluklar birden fazla ise, replace () eylemi boşluk bırakma işlemini gerçekleştirir ve kaldırır.

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

Bir Dizedeki boşluk sayısını saymak için.

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

Desen .quote ("?") Değişmez desen Dizesi döndürür.


0

Ben daha iyi bir çözüm olarak regex kullanarak ikinci cevap bulmadan önce benim yöntem. Belki birisinin bu koda ihtiyacı vardır.

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

İlginç, ama beyaz boşluk sadece boşluklardan daha fazlası anlamına geliyor.
Laur Ivan

@LaurIvan ne demek istiyorsun?
trinity420

bu girişin\s düzenli ifadelerde (boşluk, sekme, yeni satır, form besleme) ne anlama geldiğiyle ilgili iyi bir açıklaması vardır .
Laur Ivan

@LaurIvan Bağlantınız koptu, ancak haklısınız. Bu sorun, girdi dizesi üzerinden yineleme yaparak, alfabetik olmayan, sayısal olmayan ve boşluk olmayan her karakteri kaldırarak çözülebilir.
trinity420

0

Akış sürümü, boşlukları ve sekmeleri filtreler.

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

Dizenin herhangi bir yerinde beyaz boşluğu kaldırmak için en basit yöntem.

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

Yukarıdaki çözüm, herhangi bir java işlevi kullanmadan O (n) karmaşıklığına sahip algoritmadır.


-1

Lütfen aşağıdaki kodu kullanın

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

Gecikme için üzgünüm! Aradığınız en iyi ve en verimli yanıtı aşağıda bulabilirsiniz:

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

Yani bu örneğin çıktısı şöyle olacak: Benim adım kingkon.

Ancak bu yöntem dizenizin sahip olabileceği "\ n" karakterini de kaldıracaktır. Yani bunu istemiyorsanız sadece bu basit yöntemi kullanın:

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

Ve öndeki ve arkadaki boşlukları da şeritlemek istiyorsanız ekleyin:

str = str.trim();

-1

ReplaceAll yönteminin çok daha kolay olduğunu biliyorum ama bunu da göndermek istedim.

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
Bu işe yarıyor olsa da, en kolay çözümden uzaktır.
platzhersh

-1

String Tokenizer kullanılabilir

 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());
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.