如何使用.NET(带换行符)获取字符串中的行数

本文关键字:字符串 获取 NET 何使用 换行符 | 更新日期: 2023-09-27 18:19:33

我需要计算字符串中的行数。任何换行符都可以是字符串中可以存在的字符(CR、LF或CRLF)。

So possible new line chars:
* 'n
* 'r
* 'r'n

例如,使用以下输入:

This is ['n]
an string that ['r]
has four ['r'n]
lines

该方法应返回4行。你知道任何内置函数,或者有人已经实现了它吗?

static int GetLineCount(string input)
{
   // could you provide a good implementation for this method?
   // I want to avoid string.split since it performs really bad
}

注意:性能对我来说很重要,因为我能读懂大字符串。

如何使用.NET(带换行符)获取字符串中的行数

int count = 0;
int len = input.Length;
for(int i = 0; i != len; ++i)
  switch(input[i])
  {
    case ''r':
      ++count;
      if (i + 1 != len && input[i + 1] == ''n')
        ++i;
      break;
    case ''n':
    // Uncomment below to include all other line break sequences
    // case ''u000A':
    // case ''v':
    // case ''f':
    // case ''u0085':
    // case ''u2028':
    // case ''u2029':
      ++count;
      break;
  }

只需扫描,计算换行,在'r的情况下,测试下一个字符是否为'n,如果是则跳过它。

性能对我来说很重要,因为我能读懂大字符串。

如果可能的话,尽量避免读取大字符串。例如,如果它们来自流,那么直接在流上执行这一操作非常容易,因为只需要提前读取一个字符。

这里有另一个不计算字符串末尾换行的变体:

int count = 1;
int len = input.Length - 1;
for(int i = 0; i < len; ++i)
  switch(input[i])
  {
    case ''r':
    if (input[i + 1] == ''n')
    {
      if (++i >= len)
      {
        break;
      }
    }
    goto case ''n';
        case ''n':
        // Uncomment below to include all other line break sequences
        // case ''u000A':
        // case ''v':
        // case ''f':
        // case ''u0085':
        // case ''u2028':
        // case ''u2029':
          ++count;
          break;      
  }

因此,这将"""a line""a line'n""a line'r'n"分别视为一行,依此类推

您的字符串来自文件?

我认为这一个做得很好,而且做得很快:

int count = File.ReadLines(path).Count();

发件人:如何在不读取文件的情况下获得行数结束

Regex.Matches(input, "'n|'r|'n'r").Count

这次讨论怎么样

简单的

private static int Count4(string s)
{
    int n = 0;
    foreach( var c in s )
    {
        if ( c == ''n' ) n++;
    }
    return n+1;
}

应该非常快,即使有更大的字符串。。。许多其他算法已经在那里进行了测试。什么反对这种实施?如果你不扩展到使用并行执行,我会尝试这种非常简单的方法。

完全手动实现:(你不会比这快多少)

public static int GetLineCount(string input)
{
    int lineCount = 0;
    for (int i = 0; i < input.Length; i++)
    {
        switch (input[i])
        {
            case ''r':
                {
                    if (i + 1 < input.Length)
                    {
                        i++;
                        if (input[i] == ''r')
                        {
                            lineCount += 2;
                        }
                        else
                        {
                            lineCount++;
                        }
                    }
                    else
                    {
                        lineCount++;
                    }
                }
                break;
            case ''n':
                lineCount++;
                break;
            default:
                break;
        }
    }

下面是一个类似于微软从文件中读取行的例子:

int numberOfLines = 0;
using (StreamReader sr = new StreamReader(path, encoding))
    while ((line = sr.ReadLine()) != null)
        numberOfLines += 1;

供参考/阅读:http://referencesource.microsoft.com/#mscorlib/system/io/file.cs,8d10107b7a92c5c2http://referencesource.microsoft.com/#mscorlib/system/io/file.cs,675b2259e8706c26

如果你想得到行数,你应该只计算'n,因为'r意味着回车,不会前进到新行:

static int GetLineCount(string input)
{
    return input.Count(c => c == ''n');
}