Java String.trim () จะลบช่องว่างได้กี่ช่อง?


117

ใน Java ฉันมีสตริงแบบนี้:

"     content     ".

จะString.trim()ลบช่องว่างทั้งหมดในด้านเหล่านี้หรือเพียงช่องว่างเดียวในแต่ละด้าน?


197
สำหรับผู้ลงคะแนน: พฤติกรรมของคุณเป็นผู้มีอำนาจ คำถามนี้มีรายละเอียดและเฉพาะเจาะจงเขียนอย่างชัดเจนและเรียบง่ายเป็นที่สนใจของโปรแกรมเมอร์คนอื่น ๆ อย่างน้อยหนึ่งคน คนอาจไม่รู้ว่าจะหา javadoc หรือซอร์สโค้ดได้ที่ไหน หน้าที่ของเราคือช่วยพวกเขาไม่ใช่ทุบตีพวกเขาเพราะงมงาย
glmxndr

14
@subtenante คุณถูกต้อง ฉันเคยปกป้องคนที่ถามคำถาม google'ish มาก่อนด้วยซ้ำ อย่างไรก็ตามสิ่งที่ง่ายเช่นนี้ควรได้รับการทดสอบด้วยตัวเองและ IMO ไม่ควรรับประกันการโพสต์คำถามในไซต์ถาม - ตอบ ชื่อเรื่องทำให้เข้าใจผิดและ Q นั้นเสียเวลาสำหรับทุกคนที่อ่าน
คริส

9
@ คริส: oneat ให้โอกาสฉันดูซอร์สโค้ด ฉันได้เรียนรู้มากมายเกี่ยวกับการตัดแต่ง () ฉันจะไม่มีอย่างอื่น ทุกคนต้องรับผิดชอบต่อการใช้เวลาของตัวเอง oneat ไม่ควรถูกตำหนิที่เราไม่สามารถหากำไรจากคำถามที่ดูเหมือนไร้เดียงสาของเขาได้
glmxndr

1
@skaffman: (c) ควร "ลองใช้ดู" และจากนั้น (d) ถามใน SO
Mac

2
คำถามนี้ดูเหมือนจะไม่ตรงประเด็นเนื่องจากเป็นคำถามเกี่ยวกับสิ่งที่ทุกคนควรจะพบในคู่มือและการทดสอบภายในเวลาไม่ถึงหนึ่งนาที
Jasper

คำตอบ:


168

ทั้งหมดของพวกเขา

ส่งคืน : สำเนาของสตริงนี้โดยลบช่องว่างนำหน้าและต่อท้ายออกหรือสตริงนี้หากไม่มีช่องว่างนำหน้าหรือต่อท้าย

~ อ้างจากเอกสาร Java 1.5.0

(แต่ทำไมคุณไม่ลองดูด้วยตัวคุณเองล่ะ?)


1
ฉันต้องลงคะแนนเนื่องจากคำตอบนี้ไม่ครอบคลุมถึงความหมายของเอกสารโดยใช้ "ช่องว่าง" มันดูเหมือนจะเป็นตรรกะที่จะChararacter.isWhitespaceเป็นจริง แต่นั่นไม่ใช่สิ่งที่หมายถึง "ช่องว่าง" ..
user2864740

7
@ user2864740: คำตอบนี้ไม่ได้มีวัตถุประสงค์ที่จะวิเคราะห์ที่ครอบคลุมของtrim, isWhiteSpaceฯลฯ หรือการอภิปรายของความคลุมเครือในเอกสารจาวา; เป็นคำตอบที่ตรงไปตรงมาสำหรับคำถามเฉพาะที่ถามข้างต้นนั่นคือtrimวิธีนี้จะลบช่องว่างเดียวหรือหลายช่องว่าง?
LukeH

ฉันรู้ว่ามันไม่ใช่ ฉันโหวตไม่ลงเพราะไม่สามารถชี้ให้เห็นได้แม้จะผ่านไปแล้วก็ตาม ไม่ว่าในกรณีใดฉันจะไม่สามารถยกเลิกการโหวตของฉันได้เว้นแต่จะมีการอัปเดต (อย่างไรก็ตามน้อยที่สุด)
user2864740

33

จากซอร์สโค้ด (ถอดรหัส):

  public String trim()
  {
    int i = this.count;
    int j = 0;
    int k = this.offset;
    char[] arrayOfChar = this.value;
    while ((j < i) && (arrayOfChar[(k + j)] <= ' '))
      ++j;
    while ((j < i) && (arrayOfChar[(k + i - 1)] <= ' '))
      --i;
    return (((j > 0) || (i < this.count)) ? substring(j, i) : this);
  }

สองตัวwhileที่คุณเห็นหมายถึงอักขระทั้งหมดที่มี Unicode อยู่ด้านล่างอักขระช่องว่างที่จุดเริ่มต้นและจุดสิ้นสุดจะถูกลบออก


27

หากมีข้อสงสัยให้เขียนแบบทดสอบหน่วย:

@Test
public void trimRemoveAllBlanks(){
    assertThat("    content   ".trim(), is("content"));
}

หมายเหตุ : แน่นอนว่าการทดสอบ (สำหรับ JUnit + Hamcrest) ไม่ล้มเหลว


43
ขอให้โปรแกรมเมอร์มือใหม่ที่เพิ่งเรียนรู้วิธีการทำ System.out.println ทำการทดสอบหน่วยเพื่อดูว่าผลลัพธ์เป็นอย่างไร ...
jaxkodex

26

สิ่งหนึ่งที่จะชี้ให้เห็นก็คือ String.trim มีคำจำกัดความที่แปลกประหลาดของ "ช่องว่าง" ไม่ได้ลบช่องว่าง Unicode แต่ยังลบอักขระควบคุม ASCII ที่คุณอาจไม่ใช้ช่องว่าง

วิธีนี้อาจใช้เพื่อตัดช่องว่างจากจุดเริ่มต้นและจุดสิ้นสุดของสตริง ในความเป็นจริงมันจะจดจ้องอักขระควบคุม ASCII ทั้งหมดด้วย

หากเป็นไปได้คุณอาจต้องการใช้ StringUtils.strip () ของ Commons Lang ซึ่งจัดการกับช่องว่าง Unicode ด้วย (และเป็น null-safe ด้วย)


3
ดูเหมือนจะเป็นการกำกับดูแลที่แย่มากในส่วนของนักออกแบบ .. และการทำงานด้านเทคนิคมากเกินไปของเอกสารก็ไม่ได้ช่วยอะไรมาก
user2864740

2
ไชโย! คุณตอบคำถามที่ง่ายที่สุดที่เคยถามใน StackOverflow และพบว่ามีอะไรที่ชาญฉลาดที่จะพูดถึง คุณเป็นเครดิตสำหรับการแข่งขัน
Mark McKenna

3
@MarkMcKenna: ฉันพบว่าคำถามการเขียนโปรแกรมที่เรียบง่ายสุด ๆ เหล่านี้ (การตัดแต่งสตริงการค้นหานามสกุลไฟล์ ฯลฯ ) มักจะมีความซับซ้อนซ่อนอยู่ นั่นเป็นเรื่องที่ไม่แยแสเกี่ยวกับงานฝีมือและเครื่องมือของเรา
Thilo

15

ดูAPIสำหรับคลาส String:

ส่งคืนสำเนาของสตริงโดยเว้นช่องว่างนำหน้าและต่อท้าย

ช่องว่างทั้งสองด้านจะถูกลบออก:

โปรดทราบว่าtrim()ไม่เปลี่ยนอินสแตนซ์ String จะส่งคืนวัตถุใหม่:

 String original = "  content  ";
 String withoutWhitespace = original.trim();

 // original still refers to "  content  "
 // and withoutWhitespace refers to "content"

1
จริงๆแล้วไม่มีอะไรสามารถเปลี่ยนแปลงอินสแตนซ์ String ได้ (ยกเว้นสิ่งสกปรกบางอย่างที่อาจทำให้ VM ขัดข้อง)
AvrDragon

13

ขึ้นอยู่กับเอกสาร Java ที่นี่ที่.trim()แทนที่ '\ u0020' ซึ่งเป็นที่รู้จักกันทั่วไปว่าเป็นช่องว่าง

แต่โปรดทราบว่า '\ u00A0' ( Unicode NO-BREAK SPACE &nbsp; ) จะถูกมองว่าเป็นช่องว่างด้วยและ.trim()จะไม่ลบสิ่งนี้ออกไป โดยเฉพาะอย่างยิ่งใน HTML

ในการลบออกฉันใช้:

tmpTrimStr = tmpTrimStr.replaceAll("\\u00A0", "");

ตัวอย่างของปัญหานี้ได้กล่าวถึงที่นี่


จาก Javadoc จะลบช่องว่างที่นำหน้าและต่อท้ายซึ่งรวมถึงช่องว่างแท็บการคืนค่าการขึ้นบรรทัดใหม่ฟีดแบบฟอร์ม ... และไม่รวมอักขระที่ไม่นำหน้าหรือต่อท้าย
Marquis of Lorne

ขอบคุณมันช่วยฉันจัดสรร
Asad Haider

8

ตัวอย่าง Java ที่trim()ลบช่องว่าง:

public class Test
{
    public static void main(String[] args)
    {
        String str = "\n\t This is be trimmed.\n\n";

        String newStr = str.trim();     //removes newlines, tabs and spaces.

        System.out.println("old = " + str);
        System.out.println("new = " + newStr);
    }
}

เอาท์พุท

old = 
 This is a String.


new = This is a String.

4

จาก java docs (ซอร์สคลาสสตริง)

/**
 * Returns a copy of the string, with leading and trailing whitespace
 * omitted.
 * <p>
 * If this <code>String</code> object represents an empty character
 * sequence, or the first and last characters of character sequence
 * represented by this <code>String</code> object both have codes
 * greater than <code>'&#92;u0020'</code> (the space character), then a
 * reference to this <code>String</code> object is returned.
 * <p>
 * Otherwise, if there is no character with a code greater than
 * <code>'&#92;u0020'</code> in the string, then a new
 * <code>String</code> object representing an empty string is created
 * and returned.
 * <p>
 * Otherwise, let <i>k</i> be the index of the first character in the
 * string whose code is greater than <code>'&#92;u0020'</code>, and let
 * <i>m</i> be the index of the last character in the string whose code
 * is greater than <code>'&#92;u0020'</code>. A new <code>String</code>
 * object is created, representing the substring of this string that
 * begins with the character at index <i>k</i> and ends with the
 * character at index <i>m</i>-that is, the result of
 * <code>this.substring(<i>k</i>,&nbsp;<i>m</i>+1)</code>.
 * <p>
 * This method may be used to trim whitespace (as defined above) from
 * the beginning and end of a string.
 *
 * @return  A copy of this string with leading and trailing white
 *          space removed, or this string if it has no leading or
 *          trailing white space.
 */
public String trim() {
int len = count;
int st = 0;
int off = offset;      /* avoid getfield opcode */
char[] val = value;    /* avoid getfield opcode */

while ((st < len) && (val[off + st] <= ' ')) {
    st++;
}
while ((st < len) && (val[off + len - 1] <= ' ')) {
    len--;
}
return ((st > 0) || (len < count)) ? substring(st, len) : this;
}

โปรดทราบว่าหลังจากเริ่มต้นและความยาวแล้วจะเรียกใช้วิธีการย่อยของคลาส String


โดยที่ "ช่องว่าง" คือ "อักขระที่มีค่าน้อยกว่าหรือเท่ากับ \ x20" .. brillant
user2864740

3

trim()จะลบช่องว่างที่นำหน้าและต่อท้ายทั้งหมด แต่โปรดทราบ: สตริงของคุณจะไม่เปลี่ยนแปลง trim()จะส่งคืนอินสแตนซ์สตริงใหม่แทน


มันจะลบช่องว่างที่
Marquis of Lorne

3

หากอินพุตสตริงของคุณคือ:

String a = "   abc   ";
System.out.println(a);

ใช่ผลลัพธ์จะเป็น "abc"; แต่ถ้าอินพุตสตริงของคุณคือ:

String b = "    This  is  a  test  "
System.out.println(b);

เอาต์พุตจะเป็นThis is a test ดังนั้นการตัดแต่งจะลบช่องว่างก่อนอักขระตัวแรกของคุณและหลังอักขระสุดท้ายของคุณในสตริงเท่านั้นและละเว้นช่องว่างภายใน นี่เป็นส่วนหนึ่งของรหัสของฉันที่ปรับStringวิธีการตัดแต่งในตัวเล็กน้อยเพื่อลบช่องว่างด้านในและลบช่องว่างก่อนและหลังอักขระตัวแรกและตัวสุดท้ายของคุณในสตริง หวังว่าจะช่วยได้

public static String trim(char [] input){
    char [] output = new char [input.length];
    int j=0;
    int jj=0;
    if(input[0] == ' ' )    {
        while(input[jj] == ' ') 
            jj++;       
    }
    for(int i=jj; i<input.length; i++){
      if(input[i] !=' ' || ( i==(input.length-1) && input[input.length-1] == ' ')){
        output[j]=input[i];
        j++;
      }
      else if (input[i+1]!=' '){
        output[j]=' ';
        j++;
      }      
    }
    char [] m = new char [j];
    int a=0;
    for(int i=0; i<m.length; i++){
      m[i]=output[a];
      a++;
    }
    return new String (m);
  }

ข้อความสองประโยคแรกในคำตอบนี้ผิดธรรมดาผลลัพธ์จะไม่เป็น "abc" บางทีคุณอาจลืม.trim()ในSystem.out.println(a);?
Arjan


2

สิ่งหนึ่งที่สำคัญมากคือสตริงที่สร้างจาก "ช่องว่างสีขาว" ทั้งหมดจะส่งคืนสตริงว่าง

ถ้า a string sSomething = "xxxxx"ซึ่งxแทนช่องว่างสีขาวsSomething.trim()จะส่งคืนสตริงว่าง

ถ้าstring sSomething = "xxAxx"ที่xยืนสำหรับพื้นที่สีขาวจะกลับมาsSomething.trim()A

ถ้าsSomething ="xxSomethingxxxxAndSomethingxElsexxx", sSomething.trim()จะกลับมาSomethingxxxxAndSomethingxElseแจ้งให้ทราบว่าจำนวนของxระหว่างคำจะไม่ถูกเปลี่ยนแปลง

หากคุณต้องการให้สตริงแพ็คเก็ตเรียบร้อยรวมtrim()กับ regex ดังที่แสดงในโพสต์นี้: จะลบช่องว่างสีขาวที่ซ้ำกันในสตริงโดยใช้ Java ได้อย่างไร? .

คำสั่งซื้อไม่มีความหมายสำหรับผลลัพธ์ แต่trim()อันดับแรกจะมีประสิทธิภาพมากกว่า หวังว่าจะช่วยได้


2

หากต้องการเก็บเพียงอินสแตนซ์เดียวสำหรับ String คุณสามารถใช้สิ่งต่อไปนี้

str = "  Hello   ";

หรือ

str = str.trim();

จากนั้นค่าของstrString จะเป็นstr = "Hello"



0

Javadocสำหรับ String มีรายละเอียดทั้งหมด ลบช่องว่าง (ช่องว่างแท็บ ฯลฯ ) จากปลายทั้งสองและส่งคืนสตริงใหม่


0

หากคุณต้องการที่จะตรวจสอบสิ่งที่จะทำวิธีการบางอย่างที่คุณสามารถใช้BeanShell เป็นภาษาสคริปต์ที่ออกแบบมาให้ใกล้เคียงกับ Java มากที่สุด โดยทั่วไปแล้วจะตีความ Java ด้วยการผ่อนคลายบางอย่าง อีกทางเลือกหนึ่งคือภาษาGroovy ภาษาสคริปต์ทั้งสองนี้ให้ลูป Read-Eval-Print ที่สะดวกในการรู้จากภาษาที่ตีความ ดังนั้นคุณสามารถเรียกใช้คอนโซลและพิมพ์:

"     content     ".trim();

คุณจะเห็น"content"ผลลัพธ์หลังจากกดEnter(หรือCtrl+Rใน Groovy console)


6
ดังนั้นเพื่อให้เข้าใจวิธีการใน Java เขาควรไปเรียนรู้ภาษาใหม่ทั้งหมด จริงๆ?
james.garriss

0
String formattedStr=unformattedStr;
formattedStr=formattedStr.trim().replaceAll("\\s+", " ");

สิ่งนี้ไม่เกี่ยวข้องกับคำถาม
Mark McKenna

2
@ มาร์ค แต่บังเอิญว่ามันคือสิ่งที่ฉันกำลังมองหาเมื่อเปิดคำถามนี้ ...
Armfoot

มันยังไม่มีจุดหมาย trim()ทำสิ่งที่repkaceAll()จะทำอยู่แล้วถ้ามีอะไรเหลือให้ทำ
Marquis of Lorne

@EJP การแทนที่ทั้งหมดจะแทนที่ช่องว่างในสตริงด้วยช่องว่างเดียวในขณะที่การตัดแต่งจะจัดการเฉพาะช่องว่างนำหน้าและต่อท้ายเท่านั้น
กฤษณะ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.