49

我正在从字符串中删除文本以及用空行替换每一行的内容。

一些背景: 我正在编写一个比较两个字符串的比较函数。它一切正常,并显示在两个单独的网络浏览器中。当我尝试在浏览器上向下滚动时,字符串的长度不同,我想用空行替换要删除的文本,以便我的字符串长度相同。

在下面的代码中,我希望计算 aDiff.Text 有多少行

这是我的代码:

public string diff_prettyHtmlShowInserts(List<Diff> diffs)
    {
        StringBuilder html = new StringBuilder();

        foreach (Diff aDiff in diffs)
        {
            string text = aDiff.text.Replace("&", "&amp;").Replace("<", "&lt;")
              .Replace(">", "&gt;").Replace("\n", "<br>"); //&para;
            switch (aDiff.operation)
            {

                case Operation.DELETE:                              
                   //foreach('\n' in aDiff.text)
                   // {
                   //     html.Append("\n"); // Would like to replace each line with a blankline
                   // }
                    break;
                case Operation.EQUAL:
                    html.Append("<span>").Append(text).Append("</span>");
                    break;
                case Operation.INSERT:
                    html.Append("<ins style=\"background:#e6ffe6;\">").Append(text)
                        .Append("</ins>");
                    break;
            }
        }
        return html.ToString();
    }
4

11 回答 11

86

方法一:

int numLines = aDiff.text.Length - aDiff.text.Replace _
                   (Environment.NewLine, string.Empty).Length;

方法二:

int numLines = aDiff.text.Split('\n').Length;

两者都会为您提供文本中的行数。

于 2012-06-25T12:31:44.593 回答
17

不分配新字符串或字符串数​​组的变体

private static int CountLines(string str)
{
    if (str == null)
        throw new ArgumentNullException("str");
    if (str == string.Empty)
        return 0;
    int index = -1;
    int count = 0;
    while (-1 != (index = str.IndexOf(Environment.NewLine, index + 1)))
        count++;

   return count + 1;
}
于 2016-12-02T09:07:20.023 回答
14

您还可以使用 Linq 来计算行的出现次数,如下所示:

int numLines = aDiff.Count(c => c.Equals('\n')) + 1;

迟到了,但提供了其他答案的替代方案。

于 2018-01-19T08:55:30.267 回答
7

效率低下,但仍然:

var newLineCount = aDiff.Text.Split('\n').Length -1;
于 2012-06-25T12:32:10.700 回答
6

我对不同的方法(Split、Replace、for loop over chars、Linq.Count)进行了一系列性能测试,获胜者是 Replace 方法(当字符串小于 2KB 时,Split 方法稍快,但不多)。

但是接受的答案中有2个错误。一个错误是当最后一行不以换行符结尾时,它不会计算最后一行。另一个错误是,如果您在 Windows 上读取具有 UNIX 行结尾的文件,则它不会计算任何行,因为 Environment.Newline\r\n存在且不存在(您始终可以使用\n,因为它是行结尾的最后一个字符UNIX 和 Windows)。

所以这里有一个简单的扩展方法......

public static int CountLines(this string text)
{
    int count = 0;
    if (!string.IsNullOrEmpty(text))
    {
        count = text.Length - text.Replace("\n", string.Empty).Length;

        // if the last char of the string is not a newline, make sure to count that line too
        if (text[text.Length - 1] != '\n')
        {
            ++count;
        }
    }

    return count;
}
于 2016-06-26T04:45:33.117 回答
4

高效且成本最低的内存。

Regex.Matches( "Your String" , System.Environment.NewLine).Count ;

当然,我们可以扩展我们的字符串类

using System.Text.RegularExpressions ;

public static class StringExtensions
{
    /// <summary>
    /// Get the nummer of lines in the string.
    /// </summary>
    /// <returns>Nummer of lines</returns>
    public static int LineCount(this string str)
    {
        return Regex.Matches( str , System.Environment.NewLine).Count ;
    }
}

参考 : µBio , Dieter Meemken

于 2018-08-27T09:39:09.100 回答
4
int newLineLen = Environment.NewLine.Length;
int numLines = aDiff.text.Length - aDiff.text.Replace(Environment.NewLine, string.Empty).Length;
if (newLineLen != 0)
{
    numLines /= newLineLen;
    numLines++;
}

稍微更健壮,占第一行,其中不会有换行符。

于 2016-01-20T15:04:20.410 回答
3

在这里聚会迟到了,但我认为这可以处理所有行,甚至最后一行(至少在 Windows 上):

Regex.Matches(text, "$", RegexOptions.Multiline).Count; 
于 2019-10-05T16:10:20.807 回答
3

为了方便起见,我将来自poncha的解决方案放在了一个很好的扩展方法中,所以你可以像这样简单地使用它:

int numLines = aDiff.text.LineCount();

编码:

/// <summary>
/// Extension class for strings.
/// </summary>
public static class StringExtensions
{
    /// <summary>
    /// Get the nummer of lines in the string.
    /// </summary>
    /// <returns>Nummer of lines</returns>
    public static int LineCount(this string str)
    {
        return str.Split('\n').Length;
    }
}

玩得开心...

于 2016-04-12T12:55:19.463 回答
3
using System.Text.RegularExpressions;

Regex.Matches(text, "\n").Count

考虑到速度和内存使用情况,我认为计算出现次数'\n'是最有效的方法。

使用split('\n')是一个坏主意,因为它会生成新的字符串数组,因此性能和效率都很差!特别是当您的字符串变大并包含更多行时。

用空字符替换'\n'字符并计算差异也不是很有效,因为它应该做一些操作,比如搜索、创建新字符串和内存分配等。

您可以只执行一项操作,即search。因此,正如@lokimidgard 建议的那样,您可以只计算'\n'字符串中字符的出现次数。

值得一提的是,搜索'\n'字符比搜索"\r\n"(或Environment.NewLine在 Windows 中)要好,因为前者 (ie '\n') 适用于 Unix 和 Windows 行尾。

于 2018-08-08T15:05:48.517 回答
2
public static int CalcStringLines(string text)
{
    int count = 1;
    for (int i = 0; i < text.Length; i++)
    {
        if (text[i] == '\n') count++;
    }

    return count;
}

这是最快/最简单/无内存分配的方法......

于 2020-06-30T17:04:15.630 回答