簡體   English   中英

使用正則表達式(.NET Framework、C#)刪除所有以“**”開頭的行(注釋)

[英]Remove all lines (comments) starting with “**” by using Regex (.NET Framework, C#)

我正在開發一個讀取和處理文本文件的應用程序。 這些文本文件具有以下結構:

** A comment
* A command
Data, data, data
** Some other comment
* Another command
1, 2, 3
4, 5, 6

我使用string text = File.ReadAllText(file);將整個文本文件存儲在內存中string text = File.ReadAllText(file); . 但是,我想刪除所有注釋行,即所有以"**"開頭的行。

這可以通過以下方法實現:

// this method also removes any white-spaces (this is intended)
string RemoveComments(string textWithComments)
{
    string textWithoutComments = null;

    string[] split = Regex.Split(text.Replace(" ", null), "\r\n|\r|\n").ToArray();
    foreach (string line in split)
        if (line.Length >= 2 && line[0] == '*' && line[1] == '*') continue;
        else textWithoutComments += line + "\r\n";

    return textWithoutComments;
}

然而,這對於大文件來說實際上非常慢。 我還認為可以用一行代碼(可能使用正則表達式)替換整個方法。 我怎樣才能做到這一點(我也從未使用過正則表達式)。

PS:我也想避免StreamReader s。

編輯

示例文件如下所示:

** Initial comment
*Command-0
** Some Comment: Header: Text
** Some text: text
*Command-1
**
** Some comment or text
**
*Command-2
*Command-3
      1,            2,            3
      2,            2,            4
      3,            2,            5
** END COMMENT

每次字符串的大小發生變化時,連接字符串都會重新分配內存。

StringBuilder 不會經常重新分配,並且會顯着減少*運行時間

string RemoveComments(string textWithComments)
{
    StringBuilder textWithoutComments = new StringBuilder();

    string[] split = text.Replace(" ", null).Split('\r', '\n');
    foreach (string line in split)
        if (line.Length >= 2 && line[0] == '*' && line[1] == '*') continue;
        else textWithoutComments.Append(line + "\r\n");

    return textWithoutComments.ToString();
}

在 Aluan 的建議中編輯

為什么不只是:

var text = @"** A comment
* A command
Data, data, data
** Some other comment
* Another command
1, 2, 3
4, 5, 6";

var textWithoutComments = Regex.Replace(text, @"(^|\n)\*\*.*(?=\n)", string.Empty); //this version will leave a \n at the beginning of the string if the text starts with a comment.
var textWithoutComments = Regex.Replace(text, @"(^\*\*.*\r\n)|((\r\n)\*\*.*($|(?=\r\n)))", string.Empty); //this versioh deals with that problem, for a longer regex that treats the first line differently than the other lines (consumes the \n rather than leaving it in the text)

不知道性能,我沒有准備好的測試數據......

PS:我也傾向於相信,如果你想要最佳性能,一些流媒體可能是理想的,如果這樣可以讓后面的處理更容易,你總是可以從方法中返回一個字符串。 我認為該線程中的大多數人都建議將 StreamReader 用於迭代/讀取/解釋部分,而不管您決定構建的返回類型如何。

我知道你說你不想使用 StreamReader,但是下面的代碼在我的電腦上可以在不到半秒的時間內處理 400,000 行。 它簡單、直接且快速。

static void RemoveCommentsAndWhitespace(string filePath)
{
    if (!File.Exists(filePath))
    {
        Console.WriteLine($"ERR: The file '{filePath}' does not exist.", nameof(filePath));
    }

    string outfile = filePath + ".out";

    using StreamReader sr = new StreamReader(filePath);
    using StreamWriter sw = new StreamWriter(outfile);
    string line;

    while ((line = sr.ReadLine()) != null)
    {
        string tmp = line.Replace(" ", string.Empty);
        if (tmp.StartsWith("**"))
        {
            continue;
        }

        sw.WriteLine(tmp);
    }

    Console.WriteLine($"Wrote to {outfile}.");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM