首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Regex (.NET框架,C#)删除以"**“开头的所有行(注释)

使用Regex (.NET框架,C#)删除以"**“开头的所有行(注释)
EN

Stack Overflow用户
提问于 2020-08-24 21:57:29
回答 3查看 420关注 0票数 0

我正在开发一个读取和处理文本文件的应用程序。这些文本文件的结构如下:

代码语言:javascript
复制
** A comment
* A command
Data, data, data
** Some other comment
* Another command
1, 2, 3
4, 5, 6

我使用string text = File.ReadAllText(file);将整个文本文件存储在内存中。但是,我想删除所有作为注释的行,即以"**"开头的所有行。

这可以通过以下方法实现:

代码语言:javascript
复制
// 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;
}

然而,对于大文件来说,这是非常慢的。我还认为可以用一行代码替换整个方法(可能通过使用Regex)。我如何做到这一点(我也从来没有使用regex)。

PS:我也想避免StreamReader

编辑

示例文件如下所示:

代码语言:javascript
复制
** 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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-24 22:23:25

为什么不只是:

代码语言:javascript
复制
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用于迭代/读取/解释部分,而不管您决定构建哪种返回类型。

票数 2
EN

Stack Overflow用户

发布于 2020-08-24 22:21:48

每当字符串的大小发生变化时,连接字符串将重新分配内存。

StringBuilder不会像以前那样频繁地重新分配,并且会显著减少运行时

代码语言:javascript
复制
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的建议中编辑了

票数 2
EN

Stack Overflow用户

发布于 2020-08-24 23:21:07

我知道您说过不想使用StreamReader,但是下面的代码可以在我的计算机上用不到半秒钟的时间处理40万行。它简单,直截了当,快速。

代码语言:javascript
复制
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}.");
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63569225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档