1. 程式人生 > >java.lang.String中的trim()方法的詳細說明

java.lang.String中的trim()方法的詳細說明

String.Trim()方法到底為我們做了什麼,僅僅是去除字串兩端的空格嗎?

一直以為Trim()方法就是把字串兩端的空格字元給刪去,其實我錯了,而且錯的比較離譜。

首先我直接反編譯String類,找到Trim()方法:

public string Trim()
{
    return this.TrimHelper(WhitespaceChars, 2);
}

TrimHelper方法有兩個引數,第一個引數名WhitespaceChars,首字母盡然是大寫的,肯定有文章,真不出我所料:

internal static readonly char[] WhitespaceChars;

 這裡只是定義它,沒有賦值,而且是靜態的,我們看看建構函式去,果然找到:

static String()
{ Empty = ""; WhitespaceChars = new char[] { '/t', '/n', '/v', '/f', '/r', ' ', '/x0085', '/x00a0', '?', ' ', ' ', ' ', ' ', '?', '?', '?', '?', '?', ' ', '?', '?', '/u2028', '/u2029', ' ', '?' }; }   Trim方法就是把字串兩端的這些字元給刪去?我很堅定的猜想到。

繼續我們的探索,直接反編譯TrimHelper,哇,也許這個才是我想要的,私有的TrimHelper方法:

private string TrimHelper(char[] trimChars, int trimType)
{
    int num = this.Length - 1;
    int startIndex = 0;
    if (trimType != 1)
    {
        startIndex = 0;
        while (startIndex < this.Length)
        {
            int index = 0;
            char ch = this[startIndex];
            index = 0;
            while
(index < trimChars.Length) { if (trimChars[index] == ch) { break; } index++; } if (index == trimChars.Length) { break; } startIndex++; } } if (trimType != 0) { num = this.Length - 1; while (num >= startIndex) { int num4 = 0; char ch2 = this[num]; num4 = 0; while (num4 < trimChars.Length) { if (trimChars[num4] == ch2) { break; } num4++; } if (num4 == trimChars.Length) { break; } num--; } } int length = (num - startIndex) + 1; if (length == this.Length) { return this; } if (length == 0) { return Empty; } return this.InternalSubString(startIndex, length, false); }

 經過分析和執行,基本上知道了這個方法是幹什麼的了。

TrimHelper方法有兩個引數:

第一個引數trimChars,是要從字串兩端刪除掉的字元的陣列;

第二個引數trimType,是標識Trim的型別。就目前發現,trimType的取值有3個。當傳入0時,去除字串頭部的空白字元,傳入1時去除字串尾部的空白字元,傳入其他數值(比如2) 去除字串兩端的空白字元。

最後再看看真正執行字串擷取的方法:

private unsafe string InternalSubString(int startIndex, int length, bool fAlwaysCopy)
{
    if (((startIndex == 0) && (length == this.Length)) && !fAlwaysCopy)
    {
        return this;
    }
    string str = FastAllocateString(length);
    fixed (char* chRef = &str.m_firstChar)
    {
        fixed (char* chRef2 = &this.m_firstChar)
        {
            wstrcpy(chRef, chRef2 + startIndex, length);
        }
    }
    return str;
}

 原來也用指標的?第一次看到,效率應該比較高吧。
最後總結一下:
String.Trim()方法會去除字串兩端,不僅僅是空格字元,它總共能去除25種字元:
('/t', '/n', '/v', '/f', '/r', ' ', '/x0085', '/x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '?', '/u2028', '/u2029', ' ', '?')


如果你想保留其中的一個或多個(例如/t製表符,/n換行符,/r回車符等),請慎用Trim方法。

請注意,Trim刪除的過程為從外到內,直到碰到一個非空白的字元為止,所以不管前後有多少個連續的空白字元都會被刪除掉。

 最後附上兩個相關的方法(也是String類直接提供的),分別去除字串頭部空白字元的TrimStart方法和去除字串尾部空白字元的 TrimEnd方法:

TrimStart和TrimEnd方法

如果想去除字串兩端其他任意字元,可以考慮Trim他的過載兄弟:String.Trim(Char[]),傳入你想要去除的哪些字元的陣列。

原始碼奉上:

public string Trim(params char[] trimChars)
{
    if ((trimChars == null) || (trimChars.Length == 0))
    {
        trimChars = WhitespaceChars;
    }
    return this.TrimHelper(trimChars, 2);
}

空格 != 空白字元,刪除空格請使用: Trim(‘ ‘);