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); }
如有问题请大家及时拍砖。