C#中Trim(),TrimStart(),TrimEnd()的实现及用法

Trim的使用方法很简单。今天写一下.NET类库中是如何实现的。这篇文章发首页,让大家检查一下,免的自己一直按错误的理解下去。高手莫笑。

Trim()的功能:从此实例的开始位置和末尾移除空白字符的所有匹配项。

注意点:

(1)Trim 方法从当前字符串移除所有前导空白字符和尾部空白字符。遇到非空白字符时,每个前导裁剪操作和尾部裁剪操作都会停止。

(2)此方法不修改当前实例的值。而是返回一个新字符串,在该字符串中,当前实例中找到的所有前导和尾随空白字符均被移除。

(3)如果当前字符串等于 Empty 或当前实例中的所有字符由空白字符组成,该方法将返回 Empty

Trim(char[] trimChars)的功能:从此实例的开始和末尾移除数组中指定的一组字符的所有匹配项。

注意点:

(1)从此实例的开始和结尾移除 trimChars 中字符的所有匹配项后剩余的 String。如果 trimChars 为 空引用(在 Visual Basic 中为 Nothing),则改为移除空白字符。

(2)此方法不修改当前实例的值。而是返回一个新字符串,在该字符串中,移除了当前实例中找到的所有前导和尾随 trimChars 字符。

(3)如果当前字符串等于 Empty 或当前实例中的所有字符由 trimChars 数组中的字符组成,该方法将返回 Empty

 

TrimStart(char[] trimChars)的功能:从当前 String 对象移除数组中指定的一组字符的所有前导匹配项。(注意点与Trim相似)

TrimEnd(char[] trimChars)的功能:从当前 String 对象移除数组中指定的一组字符的所有尾部匹配项。(注意点与Trim相似)

更加详细的内容产看MSDN中Trim方法的讲解。

在.NET 2.0的类库中代码如下:

        private const int TrimHead = 0;
        private const int TrimTail = 1;
        private const int TrimBoth = 2;
        public static readonly String Empty = "";

  

 

 internal static readonly char[] WhitespaceChars =   
            { (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD, (char) 0x20,   (char) 0x85, 
              (char) 0xA0, (char)0x1680,
              (char) 0x2000, (char) 0x2001, (char) 0x2002, (char) 0x2003, (char) 0x2004, (char) 0x2005,
              (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B,
              (char) 0x2028, (char) 0x2029,
              (char) 0x3000, (char) 0xFEFF };

Trim()方法:

 

 public String Trim() {
            return TrimHelper(WhitespaceChars,TrimBoth);        
        }

调用了TrimHelper方法。即TrimHelper(WhitespaceChars,2);  从首尾去除空格。     

TrimHelper方法的实现:

   public String TrimHelper(char[] trimChars, int trimType) {
            //end will point to the first non-trimmed character on the right
            //start will point to the first non-trimmed character on the Left
            int end = this.Length-1;
            int start=0;

            //Trim specified characters.
            if (trimType !=TrimTail)  {
                for (start=0; start < this.Length; start++) {
                    int i = 0;
                    char ch = this[start];
                    for( i = 0; i < trimChars.Length; i++) {
                        if( trimChars[i] == ch) break;
                    }
                    if( i == trimChars.Length) { // the character is not white space
                        break;  
                    }
                }
            }
            
            if (trimType !=TrimHead) {
                for (end= Length -1; end >= start;  end--) {
                    int i = 0;    
                    char ch = this[end];                    
                    for(i = 0; i < trimChars.Length; i++) {
                        if( trimChars[i] == ch) break;
                    }
                    if( i == trimChars.Length) { // the character is not white space
                        break;  
                    }                    
                }
            }

            //Create a new STRINGREF and initialize it from the range determined above.
            int len = end -start + 1;
            if (len == this.Length) {
                // Don't allocate a new string is the trimmed string has not changed.
                return this;
            }
            else {
                if( len == 0) {
                    return String.Empty;
                }
                return InternalSubString(start, len, false);
            }
        }

  分析以上函数我们知道:

  根据传入的trimType值判断是进行首,尾或者首尾空白字符的移除。

     查看第一个for循环,判断字符串前面遇到的第一个是否为非空字符,如果为非空字符就跳出循环,记录start值。

     第二个for循环,判断字符串尾部遇到的第一个为非空字符,如果为非空字符就跳出循环,记录end值。

    根据start,end生存新的字符串。

    InternalSubString方法如下:

 

 unsafe string InternalSubString(int startIndex, int length, bool fAlwaysCopy) {
            BCLDebug.Assert( startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!");
            BCLDebug.Assert( length >= 0 && startIndex <= this.Length - length, "length is out of range!");            

            if( startIndex == 0 && length == this.Length && !fAlwaysCopy)  {
                return this;
            }
            
            String result = FastAllocateString(length);

            fixed(char* dest = &result.m_firstChar)
                fixed(char* src = &this.m_firstChar) {
                    wstrcpy(dest, src + startIndex, length);
                }

            return result;
        }

部分代码如上。

Trim(char[] trimChars)代码如下:

 

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

实现过程与Trim()方法类似,只不过trimChars字符数组被替换为自己定义的TrimChars字符数组。

TrimStart方法与Trim(char[] trimChars)方法类似。

 

 public String TrimStart(params char[] trimChars) {
            if (null==trimChars || trimChars.Length == 0) {
                trimChars=WhitespaceChars;
            }
            return TrimHelper(trimChars,TrimHead);
        }

TrimEnd方法与Trim(char[] trimChars)方法同样类似。

  

 public String TrimEnd(params char[] trimChars) {
            if (null==trimChars || trimChars.Length == 0) {
                trimChars=WhitespaceChars;
            }
            return TrimHelper(trimChars,TrimTail);
        }

  

如有问题请大家及时拍砖。

  

 

posted @ 2012-04-01 16:34  Seonwater Lee  阅读(2657)  评论(0编辑  收藏  举报