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

      

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

      

  • 相关阅读:
    MongoDB 时间截取、字符串截取、拼接(时间戳、字符串等)
    ClickHouse 参数配置
    C++函数调用栈的变化分析
    WPF中为button添加快捷键(ShortCut)的方法
    vscode中一些好用的插件介绍
    剑指Offer 2. 青蛙跳台阶问题
    切片Slice的使用
    剑指Offer 1. 斐波那契数列
    match_parent和wrap_content的区别
    字节流、字符流
  • 原文地址:https://www.cnblogs.com/thinkquan/p/trimpractice.html
Copyright © 2020-2023  润新知