从StringBuilder的末尾修剪空格而不调用ToString()。修剪()并返回到新的SB

什么是从StringBuilder的末尾调整空格而不调用ToString()的有效方法。修剪()并返回到新的SB new StringBuilder(sb.ToString().Trim())

以下是扩展方法,因此您可以这样调用它:

  sb.TrimEnd(); 

此外,它返回SB实例,允许您链接其他调用( sb.TrimEnd().AppendLine() )。

  public static StringBuilder TrimEnd(this StringBuilder sb) { if (sb == null || sb.Length == 0) return sb; int i = sb.Length - 1; for (; i >= 0; i--) if (!char.IsWhiteSpace(sb[i])) break; if (i < sb.Length - 1) sb.Length = i + 1; return sb; } 

笔记:

1)如果为Null或Empty,则返回。

2)如果实际上不需要Trim,我们正在谈论一个非常快速的返回时间,可能最昂贵的调用是对char.IsWhiteSpace的单次调用。 因此,在不需要时调用TrimEnd几乎是零费用,而不是这些ToString()。Trim()返回SB路由。

3)否则,如果需要修剪,最昂贵的是对char.IsWhiteSpace的多次调用(在第一个非空白字符处中断)。 当然,循环向后迭代; 如果所有都是空白,你最终会得到一个SB.Length为0。

4)如果遇到空格,则i索引保持在循环之外,这允许我们适当地剪切长度。 在StringBuilder中,这是非常高效的,它只是设置一个内部长度整数(内部char []保持相同的内部长度)。

UPDATE2:看看Ryan Emerle的优秀笔记如下,这些笔记纠正了我的一些误解(SB的内部工作比我做的要复杂得多):

StringBuilder在技术上是char []块的链接列表,所以我们不会在LOH中结束。 调整长度在技术上并不像更改结束索引那么简单,因为如果移动到不同的块,则必须维护容量,因此可能需要分配新的块。 不过,你只在最后设置了Length属性,所以这似乎是一个很好的解决方案。 Eric Lippert的相关详细信息: https : //stackoverflow.com/a/6524401/62195

另外,请参阅这篇讨论.NET 4.0新StringBuilder实现的好文章: http : //1024strongoxen.blogspot.com/2010/02/net-40-stringbuilder-implementation.html

-------更新--------

下面说明当StringBuilder长度被更改时会发生什么(这里对SB执行的唯一实际操作,以及仅在需要时):

  StringBuilder sb = new StringBuilder("cool \t \r\n "); sb.Capacity.Print(); // 16 sb.Length.Print(); // 11 sb.TrimEnd(); sb.Capacity.Print(); // 16 sb.Length.Print(); // 4 

更改长度后,您可以看到内部数组(m_​​ChunkChars)保持相同的大小,事实上,您可以在调试器中看到它甚至不会覆盖(在本例中为空白)字符。 他们是孤儿。

你可以试试这个:

 StringBuilder b = new StringBuilder(); b.Append("some words"); b.Append(" to test "); int count = 0; for (int i = b.Length - 1; i >= 0; i--) { if (b[i] == ' ') count++; else break; } b.Remove(b.Length - count, count); string result = b.ToString(); 

只有在有空格然后突破循环的情况下,它才会遍历结束。

或者甚至像这样:

 StringBuilder b = new StringBuilder(); b.Append("some words"); b.Append(" to test "); do { if(char.IsWhiteSpace(b[b.Length - 1])) { b.Remove(b.Length - 1,1); } } while(char.IsWhiteSpace(b[b.Length - 1])); string get = b.ToString(); 
 StringBuilder myString = new StringBuilder("This is Trim test "); if (myString[myString.Length - 1].ToString() == " ") { myString = myString.Remove(myString.Length - 1, 1); }