C# 如何检索StringBuilder行计数?

C# 如何检索StringBuilder行计数?,c#,.net,stringbuilder,C#,.net,Stringbuilder,我有一个StringBuilder实例,我正在做大量的sb.AppendLine(“测试”)例如 我如何计算出我有多少行 我看到这个类有.Length,但这告诉我总共有多少个字符 有什么想法吗?您应该能够在字符串中搜索\n的出现次数 更新: 一种方法是按换行符拆分,并按如下方式计算数组中的元素数: sb.ToString().Split('\n').length; 您可以使用自己的类包装StringBuilder,该类将在添加行时保留行数,也可以在生成器已满后保留'\n'数 Regex.Mat

我有一个
StringBuilder
实例,我正在做大量的
sb.AppendLine(“测试”)例如

我如何计算出我有多少行

我看到这个类有
.Length
,但这告诉我总共有多少个字符


有什么想法吗?

您应该能够在字符串中搜索\n的出现次数

更新: 一种方法是按换行符拆分,并按如下方式计算数组中的元素数:

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

您可以使用自己的类包装
StringBuilder
,该类将在添加行时保留行数,也可以在生成器已满后保留'\n'数

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

执行正则表达式以计算字符串中的行终止符数(例如:\r\n)。或者,将字符串加载到文本框中并进行行数计算,但这是一种常见的方法

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

您可以将string bulider数据拆分为string[]数组,然后使用string[].Length表示行数

如下所示:

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

派生您自己的行计数
StringBuilder
其中
AppendLine
生成内部行计数,并提供获取行计数值的方法。

您可以创建一个包装类,执行以下操作:

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;
    }
}
按效率排序:

  • 计算AppendLine()调用的次数
  • 在循环中调用IndexOf()
  • 使用正则表达式
  • 使用String.Split()
  • 最后一个非常昂贵,会产生大量垃圾,不要使用。

    更新

    b、 ToString().Count(c=>c=='\n')也可以在这里使用,但可能不会 效率要低得多(除了创建 字符串!)


    比从StringBuilder创建字符串并将其拆分(或创建字符串并对其进行
    regex
    ing)更快的一种更好的方法是查看StringBuilder并计算其中的
    '\n'
    字符数

    下面的扩展方法将通过字符串生成器中的字符进行枚举,然后您可以对其进行linq,直到您心满意足为止

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

    如果要使用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();
    }
    
    这导致:


    行数:5

    您考虑过计算换行符吗?计算换行符的唯一问题是StringBuilder没有方法的查找/索引-您需要使用Chars indexed属性或计算结果字符串(ToString())。如果你需要重复计算行数,这两种方法都会很低效;你能解释一下为什么这些解决方案对你来说不可行吗?我只需要一次。然而,我也意识到,我需要在某一点上插入一行,但看不到该在哪里插入。我喜欢一些更基本的问题产生大量反馈的方式。令人惊讶的是,你可以在其他地方学习和使用这些花絮,这些花絮肯定会奏效,但如果你需要重复计算行数,这并不是一个好的解决方案。当然,Jon一次或多次都没有提到他想要它。@VninayC-是的,这是我头脑中关于如何做的一个想法,我从一开始就不喜欢它,因为你必须做一个ToString()来做任何事情。当然,如果您想多次执行此操作,那么最好将其包装成能够保持计数的内容。修复了代码格式,但您可能希望将其更改为更适合C#而不是Java。嗯。。。此代码对行进行双重计数。。。例如,某人的3行附录(“a”);将导致7,而不是3@code4life Yes(当然,这取决于相关系统上
    换行符
    字符串的
    长度)。这将不计算行数,而是计算所使用的换行符。对于Linux,这是可行的,但Windows使用
    \r\n
    。如果这个答案真的应该计算所有机器上的行数,只需删除
    .tocharray()
    。我认为选项1可能会导致错误,因为它不能保证计数的AppendLine()调用将真正匹配换行的实际计数。其他的选择很有意义。嗯,新线不会从天而降。但是,是的,在这里,效率会危及可维护性。它们可能不会从天而降,但它们可以来自
    环境。换行符
    \r\n
    \n
    ,甚至来自传递给其他方法之一的内容。
    b.ToString().Count(c=>c=='\n')
    在这里也会起作用,效率可能不会低很多(除了创建字符串的单独副本!)@Gabe:我应该知道
    b.ToString().Count(c=>c=='\n')
    大约需要我的枚举数的2/3时间。我猜你指的是Regex.Matches(builder.ToString(),Environment.NewLine).Count;因为Match()只返回一个匹配项。
    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();
    }