`
fenglingyesiyu
  • 浏览: 1554 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

String.Trim()真相大揭秘(BreezeWoo 著)

F# 
阅读更多
部门上次的CodeReview会议上,留下了一道作业题,也是本篇博文所要讲述的:String.Trim()方法到底为我们做了什么,仅仅是去除字符串两端的空格吗?
很久很久以前,也就是前几个小时前,我一直以为Trim()方法就是把字符串两端的空格字符给删去,其实我错了,而且错的比较离谱。
首先我们直接用Reflector反编译String类,找到Trim()方法:
public string Trim()
{
    return this.TrimHelper(WhitespaceChars, 2);
}

(旁白:Reflector工具真是好用啊,哈哈)
看到这里,可能会感到很奇特(我也是),Trim()方法不就是去掉两端的空格吗?怎么还出现了一个TrimHelper方法?
TrimHelper方法有两个参数,第一个参数名WhitespaceChars,首字母尽然是大写的,肯定有文章,真不出我所料:
internal static readonly char[] WhitespaceChars;

这里只是定义它,没有赋值,而且是静态的,我们看看构造函数去,果然找到:
static String(){ Empty = " "; WhitespaceChars = new char[] { '\t', '\n', '\v', '\f', '\r', ' ', '\x0085', '\x00a0', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '\u2028', '\u2029', ' ', '?' };}

WhitespaceChars是在String类的静态构造方法中赋值的。
这篇文章是在记事本里面写的(Word 07打开的那个速度,实在是不敢恭维),当我将上一段代码从Reflector拷贝到记事本中,出现了变化(看下图):
(alt+p)

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

经过我大脑CPU的精确的分析和运行,基本上知道了这个方法是干什么的了。
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方法:
public string TrimStart(params char[] trimChars) { if ((trimChars == null) || (trimChars.Length == 0)) { trimChars = WhitespaceChars; } return this.TrimHelper(trimChars, 0); } public string TrimEnd(params char[] trimChars) { if ((trimChars == null) || (trimChars.Length == 0)) { trimChars = WhitespaceChars; } return this.TrimHelper(trimChars, 1); }

的确验证了我上面分析的结果,嘎嘎。
如果想去除字符串两端其他任意字符,可以考虑Trim他的重载兄弟:String.Trim(Char[]),传入你想要去除的哪些字符的数组。
源码奉上:
public string Trim(params char[] trimChars)
{
    if ((trimChars == null) || (trimChars.Length == 0))
    {
        trimChars = WhitespaceChars;
    }
    return this.TrimHelper(trimChars, 2);
}
空格 != 空白字符,删除空格请使用: Trim(‘ ‘);
分享到:
评论

相关推荐

    String.prototype.trim:适用于String.prototype.trim的ES5规范的垫片

    String.prototype.trim 符合ES5规范的String.prototype.trim填充程序。 如果不可用,请调用其“ shim”方法对String.prototype.trim进行填充。 该软件包实现了接口。 它可以在ES3支持的环境中工作,并符合规范( ...

    Js里面给String添加trim()方法,实现去掉字符串两边空格

    原生的JavaScript自ECMAScript5标准引入后,就已经提供了`String.trim()`方法来去除字符串首尾的空白字符,这为开发者带来了极大的便利。然而,在此之前,或者在某些特定环境下(如旧版本的浏览器),`String.trim()...

    js String.prototype.trim字符去前后空格的扩展

    String.Prototype.trim() trim()返回一个字符串两端空白字符被删除的新字符串,不影响原字符串。 第一种实现方式:理论上算是比较不错的 if (!String.prototype.trim) { String.prototype.trim = function () { ...

    java中string.trim()函数的作用实例及

    java中string.trim()函数的作用实例及源码 Java 中的 String.trim() 函数是一个非常常用的方法,它可以将字符串两端的空格删除,以便于字符串的处理和比较。下面我们来详细介绍 String.trim() 函数的作用实例及源码...

    Js中去掉空格经典代码

    String.prototype.Trim = function () { return this.replace(/(^\s*)|(\s*$)/g, ""); }; String.prototype.LTrim = function () { return this.replace(/(^\s*)/g, ""); }; String.prototype.RTrim = function ...

    IE8下String的Trim()方法失效的解决方法

    在JavaScript的世界里,`String.prototype.trim()`方法是一个非常实用的功能,它用于去除字符串两端的空白字符,如空格、换行符等。然而,在IE8及更早版本的Internet Explorer浏览器中,原生的`trim()`方法并未得到...

    图书管理系统

    string sql = "INSERT INTO View_1 VALUES(" + textBox1.Text.Trim() + ",'" + textBox2.Text.Trim() + "'," + textBox3.Text.Trim() + "," + textBox4.Text.Trim() + ",'" + textBox5.Text.Trim() + "','" + ...

    前端项目-string.js.zip

    或者,可能存在一个`trim()` 方法的变种,可以处理更复杂的空白字符清理。 总的来说,"string.js" 是一个增强JavaScript字符串处理能力的工具集,它填补了原生语言特性的一些空白,提高了前端开发者的生产力。无论...

    Java string.trim()究竟去掉了什么

    Java中的String.trim()方法是一个用于移除字符串两端空白字符的标准方法,然而,它所移除的不仅仅是空格字符。trim()方法真正的作用是移除字符串首尾的所有空白字符,包括空格、制表符(tab)、换行符等。在编程中,...

    字符串string.zip

    7. **String类的常用方法**:`trim()`去除两端空白,`toLowerCase()`和`toUpperCase()`实现大小写转换,`startsWith(String prefix)`和`endsWith(String suffix)`检查字符串开头和结尾。 8. **字符串与IO**:在Java...

    极品视频剪切软件Free.Video.Trim_PortableSoft

    《极品视频剪切软件Free.Video.Trim PortableSoft深度解析》 在数字时代,视频制作已经成为日常生活中不可或缺的一部分。无论是为了分享生活瞬间,还是专业的工作需求,高效、易用的视频编辑工具至关重要。今天我们...

    String.prototype.trimEnd:符合ES2019规范的String.prototype.trimEnd填充

    String.prototype.trimEnd 符合ES2019规范的String.prototype.trimEnd填充程序。 如果不可用,则调用其“ shim”方法对String.prototype.trimEnd进行填充。 该软件包实现了接口。 它可以在ES3支持的环境中工作并...

    jquery $.trim()去除字符串空格的实现方法【附图例】

    `jQuery.trim()` 是 jQuery 库中的一个非常实用的字符串处理函数,主要用来移除字符串开头和结尾的空白字符。这个函数对于数据清洗和用户输入验证非常有用,因为用户在输入时可能会在字段前后留下不必要的空格。 ##...

    前端项目-underscore.string.zip

    首先,underscore.string是underscore.js库的一个扩展,它为JavaScript的String对象添加了超过150个实用方法,涵盖了字符串处理的各个方面,如格式化、分割、查找替换、大小写转换等。这个库的设计理念是使字符串...

    2005学生系统

    else if (cbo_loginType.Text.Trim() == "" || string.IsNullOrEmpty(cbo_loginType.Text.Trim())) { MessageBox.Show("请选择登录类型!", "登录提示"); } else { UserInfo u = null; SqlConnection con = ...

    trim函数.txt

    根据提供的文件信息,可以看出这份代码主要实现了几个与字符串处理相关的功能:删除子串、删除左侧匹配的字符序列以及字符串反转。接下来将详细解释这些功能及其实现原理。 ### 1.... 此函数用于从主字符串 `szString`...

    jQuery.trim() 函数及trim()用法详解

    原生JavaScript的`String.prototype.trim()`方法是在ECMAScript 5中引入的,它与jQuery.trim()的功能相似,但IE8及以下版本不支持此方法。在这些旧版浏览器中,可以使用jQuery.trim()或者自定义的`trim()`函数来实现...

    String.prototype.trimStart:符合ES2019规范的String.prototype.trimStart填充

    String.prototype.trimStart 符合ES2019规范的String.prototype.trimStart填充程序。 如果不可用,请调用其“ shim”方法对String.prototype.trimStart进行填充。 该软件包实现了接口。 它可以在ES3支持的环境中工作...

    jquery $.trim()方法使用介绍

    - 方法的基本格式是:`$.trim(string);` - 其中`string`代表需要处理的原始字符串。 3. **兼容性注意事项:** - 在使用JavaScript原生的trim()方法时,尤其是在较旧的IE浏览器中可能会出现问题。 - 如示例所示...

Global site tag (gtag.js) - Google Analytics