2010-09-03 40 views
21

我有一個StringBuilder例如,我在做很多sb.AppendLine("test");例如。如何檢索StringBuilder行數?

如何計算出我有多少行?

我看到這個班有.Length,但它告訴我有多少個字符。

任何想法?

+0

你有沒有考慮計數換行符? – 2010-09-03 13:48:55

+0

只有計數換行符的問題是StringBuilder沒有find/index-of方法 - 您需要使用Chars索引屬性或計算結果字符串(ToString())。如果您需要重複執行行數,這兩種方法都可能效率低下。 – VinayC 2010-09-03 13:55:13

+1

喬恩,有很多非常明顯的解決方案;你能否給出上下文來解釋爲什麼這些解決方案不適合你? – tenfour 2010-09-03 14:02:23

回答

22

的效率排序:

  1. 計數您AppendLine()調用
  2. 在循環中調用的IndexOf()
  3. 使用正則表達式
  4. 使用String.Split()

最後一個是非常昂貴,併產生地段的垃圾,不要使用。

+7

我認爲選項#1可能會導致錯誤,因爲它不能保證計數的AppendLine()調用將真正匹配換行的實際數量。其他選擇具有突出的意義。 – code4life 2010-09-03 14:24:34

+1

恩,換行符不會從天而降。但是,是的,效率會危及這裏的可維護性。 – 2010-09-03 14:32:39

+8

它們可能不會從天而降,但它們可以來自'Environment.NewLine','\ r \ n','\ n',甚至來自傳遞給其他方法之一的內容。 – 2010-09-03 14:47:16

2

您應該能夠搜索字符串中\ n的出現次數。

UPDATE: 的一種方法是分裂的換行符和計數數組中元素的個數如下:

sb.ToString().Split('\n').length; 
+0

如果您需要重複行數,肯定會工作但不是一個好的解決方案。當然,Jon並沒有提到他是否想要一次或多次。 – VinayC 2010-09-03 13:58:04

+0

@VninayC - 是的,這是一個關於如何去做的想法,我從一開始就不喜歡它,因爲你必須做ToString()來做任何事情。當然,如果你想多次包裝它,那麼保持計數本身就是最好的。 – 2010-09-03 15:15:00

18

你可以換StringBuilder用自己的類將保持計數因爲它們被添加或者在你的構建器已滿之後可能會有'\ n'的數量。

Regex.Matches(builder.ToString(), Environment.NewLine).Count 
+1

+1自己的類,或者甚至可能是擴展方法。 – user7116 2010-09-03 14:10:43

+4

我想你的意思是Regex.Matches(builder.ToString(),Environment.NewLine).Count;因爲Match()只返回一個匹配。 – alex440 2013-05-08 12:00:31

0

做一個正則表達式來計算字符串中行結束符的數量(例如:\ r \ n)。或者,字符串加載到一個文本框和幹一行計數,但多數民衆贊成這樣做

4

的黑客,安永方式試試這個:

sb.ToString().Split(System.Environment.NewLine.ToCharArray()).Length; 
+2

嗯...這段代碼重複了兩行......例如sb.AppendLine(「a」)的3行;將導致7,而不是3 ...! – code4life 2010-09-03 14:15:44

+0

@ code4life是(當然取決於所討論的系統上NewLine字符串的'Length')。 – 2013-02-11 18:21:07

0

您可以分割字符串bulider數據轉換成String []數組和然後使用String []。Length爲行數。

類似如下:

String[] linestext = sb.Split(newline) 
Console.Writeline(linetext.Length) 
1

派生自己的行計數StringBuilder其中AppendLine UPS內部的線數和提供一個方法來獲得行計數的值。

6

您可以創建一個包裝類做到以下幾點:

public class Wrapper 
{ 
    private StringBuilder strBuild = null; 
    private int count = 0; 
    public Wrapper(){ 
     strBuild = new StringBuilder(); 
    } 
    public void AppendLine(String toAppendParam){ 
     strBuild.AppendLine(toAppendParam); 
     count++; 
    } 
    public StringBuilder getStringBuilder(){ 
     return strBuild; 
    } 

    public int getCount(){ 
     return count; 
    } 
} 
+3

修復了您的代碼格式,但您可能希望將其更改爲C#而不是Java的慣用語言。 – user7116 2010-09-03 14:14:28

2

UPDATEWhat Gabe said

b.ToString()。計數(C =>ç== '\ n')將在這裏工作過,並且可能無法 從創建要少得多效率(除一個單獨的 字符串!)。


一個更好的辦法,比創建從StringBuilder的字符串,並分割它(或創建的字符串, regex荷蘭國際集團吧)更快,是尋找到的StringBuilder和計數的 '\n'字符數有英寸

以下擴展方法將通過字符串生成器中的字符進行枚舉,然後您可以直接對它進行檢查,直到您的心臟滿意爲止。

public static IEnumerable<char> GetEnumerator(this StringBuilder sb) 
    { 
     for (int i = 0; i < sb.Length; i++) 
      yield return sb[i]; 
    } 

...這裏使用的,數量將是4

 StringBuilder b = new StringBuilder(); 
     b.AppendLine("Hello\n"); 
     b.AppendLine("World\n"); 

     int lineCount = b.GetEnumerator().Count(c => c =='\n'); 

+0

'b.ToString()。Count(c => c =='\ n')'也可以在這裏工作,效率可能不會太低(除了創建一個單獨的字符串副本!)。 – Gabe 2010-09-03 14:30:02

+0

@Gabe:我應該知道'b.ToString()。Count(c => c =='\ n')'大約需要2/3的枚舉器。 – 2010-09-03 14:40:17

2

如果你打算使用String.Split(),您將需要拆分爲字符串一些選項。就像這樣:

static void Main(string[] args) 
{ 
    var sb = new StringBuilder(); 
    sb.AppendLine("this"); 
    sb.AppendLine("is"); 
    sb.AppendLine("a"); 
    sb.AppendLine("test"); 

    // StringSplitOptions.None counts the last (blank) newline 
    // which the last AppendLine call creates 
    // if you don't want this, then replace with 
    // StringSplitOptions.RemoveEmptyEntries 
    var lines = sb.ToString().Split(
     new string[] { 
      System.Environment.NewLine }, 
     StringSplitOptions.None).Length; 

    Console.WriteLine("Number of lines: " + lines); 

    Console.WriteLine("Press enter to exit."); 
    Console.ReadLine(); 
} 

這導致:

Number of lines: 5