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(‘ ‘);

java.lang.String中的trim()方法的详细说明(转)的更多相关文章

  1. java.lang.String中的replace方法到底替换了一个还是全部替换了。

    你没有看错我说的就是那个最常用的java.lang.String,String可以说在Java中使用量最广泛的类了. 但是我却发现我弄错了他的一个API(也可以说是两个API),这个API是关于字符串 ...

  2. java.lang.String里面的trim()方法——删除首尾空格

    结果如图 package com.softeasy.test1; public class String_trim { public static void main(String[] args) { ...

  3. java.lang.String 类的所有方法

    java.lang.String 类的所有方法 方法摘要 char charAt(int index) 返回指定索引处的 char 值. int codePointAt(int index) 返回指定 ...

  4. java:常用类(包装类,equals和==的比较,Date,java.lang.String中常用方法,枚举enum)

    *包装类: 将基本类型封装成类,其中包含属性和方法以方便对象操作. *byte---->Byte *short--->Short *long--->Long *float---> ...

  5. java.lang.Math中的基本方法

    java.lang.Math类提供的方法都是static的,“静态引入 ”使得不必每次在调用类方法时都在方法前写上类名:             import static java.lang.Mat ...

  6. mybatis invalid comparison: java.sql.Timestamp and java.lang.String报错解决方法

    这个错的意思是:java.sql.Timestamp和java.lang.String无效的比较 错误的原因是:拿传入的时间类型参数与空字符串进行比较就会报这个异常 解决方法:只保留非null判断就可 ...

  7. java基础---->String中的split方法的原理

    这里面主要介绍一下关于String类中的split方法的使用以及原理. split函数的说明 split函数java docs的说明: When there is a positive-width m ...

  8. Java的String中的subString()方法

    方法如下: public String substring(int beginIndex, int endIndex) 第一个int为开始的索引,对应String数字中的开始位置, 第二个是截止的索引 ...

  9. java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.String错误的解决方法

    mmobjectid是在Oracle数据库中对应的是Number类型的,在JavaBean中定义的是Long类型的. List<BigDecimal> mmobjidAllFromMars ...

随机推荐

  1. logging模块的作用以及应用场景

    一.python中的logging模块 logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统.logging模块是Python的一个标准库模块,由标准库模块提供日志记录AP ...

  2. 常见python快捷键

    http://www.cnblogs.com/toutou/p/4778818.html Ctrl+/注释(取消注释)选择的行 Shift + Enter开始新行 Ctrl + Enter智能换行 T ...

  3. jQuery效果show()方法

    $("button").click(function(){ $("p").show(); }); Syntax $(selector).show(speed,e ...

  4. Python日志记录(Logging)

    日志记录跟程序的测试相关,并且在大幅度更改程序内核时很有用,它可以帮助我们找到问题和错误的所在.日志记录基本上就是收集与程序运行有关的数据,这样可以在随后进行检查或者累计数据. 1.简单示例 在Pyt ...

  5. 【bzoj2698】染色 期望

    题目描述 输入 输入一行四个整数,分别为N.M.S和T. 输出 输出一行为期望值,保留3位小数. 样例输入 5 1 2 3 样例输出 2.429 题解 期望 由于期望在任何时候都是可加的,因此只要算出 ...

  6. Bind Enum To DropDownList ?

    0. 准备测试数据 0.1 : 枚举 using System; using System.Collections.Generic; using System.Linq; using System.W ...

  7. npm scripts设置环境变量方法

    windows set NODE_ENV=production "scripts": { "release": "set NODE_ENV=produ ...

  8. 微信小程序页面跳转传参

    1.传递参数方法   使用navigatior组件 <navigator url="/pages/pull/pull?title=lalla&name=cc" hov ...

  9. [解决方案][错误代码:0x80070002]IIS7及以上伪静态报错404

    故障现象:DTCMS开启伪静态功能,VS2010预览正常,发布到IIS后报错404.0错误 (WIN7,WIN8,SERVER2008).模块IISWebCore通知MapRequestHandler ...

  10. Codeforces878E. Numbers on the blackboard

    $n \leq 100000$的数列,数字范围$-1e9,1e9$,现$q \leq 1e5$个每次问在一个区间玩游戏,能得到的最大的数.“游戏”:选相邻两个数$a_x,a_y$,然后把他们删掉,变成 ...