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

问题描述 投票:3回答:7

我需要计算一个字符串中的行数。任何换行符都可以出现在字符串中(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
}

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

c# .net string
7个回答
3
投票
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"视为仅一行,依此类推。


2
投票

你的字符串来自一个文件?

我认为这个人能做到这一点并且做得非常快:

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

来自:How to get Number Of Lines without Reading File To End


1
投票

怎么样this discussion

简单

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

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


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

0
投票
Regex.Matches(input, "\n|\r|\n\r").Count

0
投票

这是一个类似于Microsoft在从文件中读取行时如何操作的示例:

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,8d10107b7a92c5c2 http://referencesource.microsoft.com/#mscorlib/system/io/file.cs,675b2259e8706c26


0
投票

如果你想获得行数,你应该只计算\n,因为\r表示回车并且没有前进到新行:

static int GetLineCount(string input)
{
    return input.Count(c => c == '\n');
}
© www.soinside.com 2019 - 2024. All rights reserved.