Java วิธีการแทนที่ 2 หรือมากกว่าช่องว่างด้วยพื้นที่เดียวในสตริงและลบช่องว่างนำหน้าและต่อท้าย


271

กำลังมองหาวิธีที่ง่ายและรวดเร็วใน Java เพื่อเปลี่ยนสตริงนี้

" hello     there   "

สำหรับสิ่งที่มีลักษณะเช่นนี้

"hello there"

โดยที่ฉันจะแทนที่ช่องว่างหลายช่องทั้งหมดด้วยช่องว่างเดียวยกเว้นว่าฉันต้องการให้มีช่องว่างตั้งแต่หนึ่งต้นขึ้นไปที่จุดเริ่มต้นของสตริงด้วย

บางสิ่งเช่นนี้ทำให้ฉันมีบางส่วนที่นั่น

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

แต่ไม่มาก


5
คุณควรพิจารณายอมรับคำตอบ มันทำให้ง่ายขึ้นมากสำหรับคนที่มาที่หน้าในภายหลังเพื่อเลือกโซลูชันที่ชัดเจน
Paul Rooney

1
นี่เป็นวิธีที่แนะนำมากที่สุด => String nameWithProperSpacing = StringUtils.normalizeSpace (stringWithLotOfSpaces);
Kunal Vohra

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

คำตอบ:


461

ลองสิ่งนี้:

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

ดูสิ่งนี้ด้วย


ไม่มีtrim()regex

เป็นไปได้ที่จะทำสิ่งนี้ด้วยเพียงอันเดียวreplaceAllแต่มันสามารถอ่านได้น้อยกว่าtrim()วิธีแก้ปัญหา อย่างไรก็ตามมีให้ที่นี่เพียงเพื่อแสดงสิ่งที่ regex สามารถทำได้:

    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
regexp ที่ดี หมายเหตุ: การแทนที่ช่องว่าง `` ด้วย\\sจะแทนที่กลุ่มช่องว่างใด ๆ ด้วยอักขระที่ต้องการ
djmj

1
โปรดทราบว่าส่วน () + จะจับคู่ช่องว่างเดียวและแทนที่ด้วยช่องว่างเดียว บางที (<space> <space> +) จะดีกว่าดังนั้นจึงตรงกับถ้ามีหลายช่องว่างเท่านั้นและการแทนที่จะทำการเปลี่ยนสุทธิเป็นสตริง
Lee Meador

2
ดังที่ Lee Meador พูดถึง.trim().replaceAll(" +", " ")(มีสองช่องว่าง) เร็วกว่า.trim().replaceAll(" +", " ")(มีที่ว่างหนึ่งช่อง) ฉันรันการทดสอบเวลาเกี่ยวกับสตริงที่มีเพียงช่องว่างเดียวและช่องว่างคู่ทั้งหมดและมันก็มาเร็วขึ้นอย่างมากสำหรับทั้งสองเมื่อทำการดำเนินการจำนวนมาก (ล้านหรือมากกว่านั้นขึ้นอยู่กับสภาพแวดล้อม)
Gary S. Weaver

154

คุณเพียงแค่ต้องการ:

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

ที่คุณจับคู่หนึ่งหรือมากกว่าหนึ่งช่องว่างและแทนที่ด้วยช่องว่างเดียวและจากนั้นตัดช่องว่างที่จุดเริ่มต้นและจุดสิ้นสุด (คุณสามารถกลับด้านด้วยการตัดแต่งก่อนแล้วจึงจับคู่เพื่อทำให้ regex เร็วขึ้นตามที่ใครบางคนชี้)

ลองทดสอบดูสิ:

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

และมันจะกลับมา:

"hello there"

3
ฉันอาจจะตัดแต่งก่อนเพราะจากนั้นคุณประหยัดการทำงานของ regex
Michael

3
@ sarah.ferguson โปรดลบเครื่องหมายวงเล็บสุดท้าย ")" ที่ไม่ควรอยู่ในส่วนแทนที่แรกทั้งหมด ขอบคุณ - ระบบจะไม่ให้ฉันทำ! (ไม่มีอะไรที่น้อยกว่า 6 ตัวอักษรมีสิทธิ์ได้รับการแก้ไข .. )
mwarren

2
โปรดทราบว่านี่จะแทนที่หนึ่งช่องว่างด้วยช่องว่างอื่นในกรณีที่ไม่มีช่องว่างหลายช่องพร้อมกัน ไม่จำเป็นต้องทำการแทนที่ในกรณีนั้นแม้ว่าคุณอาจต้องการเนื่องจากคุณกำลังแทนที่แท็บหนึ่งด้วยช่องว่างเดียวเช่นกัน มันเป็นการดีที่จะรู้จักช่องว่างหลาย ๆ แห่งเท่านั้น
Lee Meador

2
@geowar คำถามถามแท็บที่ใด ฉันแน่ใจว่าข้างต้นไม่ได้แทนที่สัญลักษณ์☮เช่นกันสำหรับเรื่องนั้น .. และไม่ใช่✌ ...
sarah.ferguson

2
รอสักครู่ @geowar สิ่งนี้จะแทนที่ตารางเดียวด้วยช่องว่าง ฉันเพิ่งลองมัน
user1870400


20

สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน: sValue = sValue.trim().replaceAll("\\s+", " ");


1
ผู้คนแก้ไขคำตอบของฉัน ต้นฉบับคือ: sValue = sValue.replaceAll ("\ s +", "") .trim ();
หมอ

2
ได้รับการแก้ไขเพราะคำตอบเดิมของคุณลบช่องว่างทั้งหมดและนั่นไม่ใช่สิ่งที่ OP ถาม
Jose Rui Santos

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()แล้วจึงใช้คำสั่งแทนที่ regex กับผลลัพธ์


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 ครั้งและแทนที่สามครั้ง มันวนซ้ำทุกพื้นที่ภายในภายในเมธอด replaceAll () บางทีคุณสามารถเปลี่ยนมันเพื่อให้ตรงกับลำดับของช่องว่าง 2 หรือมากกว่าในคราวเดียวและลดการวนซ้ำภายใน
Lee Meador

บางที <space> + (? = <space>) อาจทำได้
Lee Meador

4

ตัด ()

ลบเฉพาะช่องว่างนำหน้า & ต่อท้าย

จาก Java Doc "ส่งคืนสตริงที่มีค่าเป็นสตริงนี้โดยลบช่องว่างนำหน้าและต่อท้าย"

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

"d ev ฉันดำ"

แทนที่ (), replaceAll ()

แทนที่สตริงว่างทั้งหมดในคำว่า

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

มีคำตอบที่ถูกต้องมากมายและฉันเห็น upvotes มากมาย อย่างไรก็ตามวิธีการดังกล่าวจะใช้งานได้ แต่ไม่ได้ปรับให้เหมาะสมจริง ๆ หรืออ่านไม่ได้จริงๆ ฉันเพิ่งเจอโซลูชันที่นักพัฒนาทุกคนจะชอบ

String nameWithProperSpacing = StringUtils.normalizeSpace( stringWithLotOfSpaces );

คุณทำเสร็จแล้ว นี่เป็นวิธีแก้ปัญหาที่สามารถอ่านได้



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

คำตอบแบบรหัสเท่านั้นจะหมดกำลังใจ โปรดคลิกที่แก้ไขและเพิ่มคำบางคำที่สรุปว่ารหัสของคุณตอบคำถามอย่างไรหรืออาจอธิบายว่าคำตอบของคุณแตกต่างจากคำตอบก่อนหน้านี้อย่างไร ขอบคุณ
Nick

1

สิ่งนี้ใช้ได้สำหรับฉัน

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

โดยที่ filter ทำตามฟังก์ชั่นและการสแกนคือสตริงอินพุต:

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> นั่นเป็นปัญหาเล็กน้อยดูเหมือนว่า
Lee Meador

1

คุณควรทำแบบนี้

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

ใส่ + ภายในวงเล็บเหลี่ยมกลม



0

ดู String.replaceAllดู

ใช้ regex "\s"และแทนที่ด้วย" "และแทนที่ด้วย

String.trimการใช้งานแล้ว


1
ใหม่ String ("hello there") .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+", "")));

} 

ถ้า String มีเพียงช่องว่างเดียวแล้วแทนที่ () จะไม่แทนที่

หากช่องว่างมีมากกว่าหนึ่งการดำเนินการแทนที่ () จะดำเนินการและลบ spacess

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

เพื่อนับจำนวนช่องว่างใน 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 ("?") ส่งคืนสตริงรูปแบบตัวอักษร


0

วิธีการของฉันก่อนที่ฉันจะพบคำตอบที่สองโดยใช้ regex เป็นทางออกที่ดีกว่า อาจมีบางคนต้องการรหัสนี้

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

น่าสนใจ แต่พื้นที่สีขาวมีความหมายมากกว่าแค่ช่องว่าง
Laur Ivan

@ Laurivan คุณหมายถึงอะไร
trinity420

รายการนี้มีคำอธิบายที่ดีเกี่ยวกับสิ่งที่มี\sไว้สำหรับนิพจน์ทั่วไป (ช่องว่างแท็บบรรทัดใหม่ฟีดฟอร์ม)
Laur Ivan

@ Laurivan ลิงก์ของคุณเสีย แต่คุณพูดถูก ปัญหานี้สามารถแก้ไขได้ด้วยการวนซ้ำผ่านสตริงอินพุตโดยลบอักขระที่ไม่ใช่ตัวอักษรตัวเลขและไม่ใช่ช่องว่างออกทั้งหมด
trinity420

0

สตรีมเวอร์ชันกรองช่องว่างและแท็บ

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


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) โดยไม่ต้องใช้ฟังก์ชั่นจาวาใด ๆ


-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

ฉันรู้ว่า replaceAll เป็นวิธีที่ง่ายกว่ามาก แต่ฉันต้องการโพสต์สิ่งนี้ด้วย

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
แม้ว่าจะได้ผล แต่ก็ยังห่างไกลจากวิธีแก้ปัญหาที่ง่ายที่สุด
platzhersh

-1

String Tokenizer สามารถใช้ได้

 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());
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.