从巨大的文件中删除不需要的字符

时间:2016-04-27 19:15:23

标签: c#

编辑:这是我目前的代码(21233664字符)

  string str = myInput.Text;
        StringBuilder sb = new StringBuilder();
        foreach (char c in str)
        {
            if ((c >= 'a' && c <= 'z') || c == '_' || c==' ')
            {
                sb.Append(c);
            }
        }
        output.Text = sb.ToString();

假设我有一个巨大的文本文件,其中包含特殊字符和带下划线的普通表达式。

以下是我正在寻找的字符串的几个示例:

  • super_test
  • 测试
  • another_super_test

如您所见,只允许小写字母带下划线。 现在,如果我在文本文件中有这些字符串,如下所示:

>  §> ˜;@  ®>  l? super_test D>ÿÿÿÿ “G? tI> €[> €? È

我面临的问题是一些孤独的信件仍然存在。在上面给出的示例中,输出将是:

l super_test t

为了获得这些字符,我必须再次查看整个文件,但这是我的问题:我怎么知道一封信是否孤独

我不确定我是否理解正则表达式的可能性,所以如果有人能给我一个提示我真的很感激。

2 个答案:

答案 0 :(得分:6)

你显然需要一个正则表达式。一个简单的是[a-z_]{2,},它将所有字符串小写的a到z字母和下划线都至少有2个字符。

解析大文件时要小心。很大,我想你会使用某种缓冲区。你需要确保你不会在一个缓冲区中获得一半的单词,而在下一个缓冲区中则另一个单词。

答案 1 :(得分:0)

您无法像其他可接受的字符一样对待空间。除了可以接受之外,空间还可以作为寂寞角色的分隔符。 (这也可能是提议的正则表达式的一个问题;我无法肯定地说。)无论如何,这样做(我认为)你想做的事情:

string str = ">  §> ˜;@  ®>  l? super_test D>ÿÿÿÿ “G? tI> €[> €? È";
StringBuilder sb = new StringBuilder();
char? firstLetterOfWord = null;
foreach (char c in str)
{
    if ((c >= 'a' && c <= 'z') || c == '_')
    {
        int length = sb.Length;
        if (firstLetterOfWord != null)
        {
            // c is the second character of a word
            sb.Append(firstLetterOfWord);
            sb.Append(c);
            firstLetterOfWord = null;
        }
        else if (length == 0 || sb[length - 1] == ' ')
        {
            // c is the first character of a word; save for next iteration
            firstLetterOfWord = c;
        }
        else
        {
            // c is part of a word; we're not first, and prev != space
            sb.Append(c);
        }
    }
    else if (c == ' ')
    {
        // If you want to eliminate multiple spaces in a row,
        // this is the place to do so
        sb.Append(' ');
        firstLetterOfWord = null;
    }
    else
    {
        firstLetterOfWord = null;
    }
}

Console.WriteLine(sb.ToString());

它适用于字符串开头和结尾的单例和完整单词。

如果您的输入包含one@two之类的内容,则输出将一起运行(onetwo,没有中间空格)。假设这不是你想要的,并且假设你不需要连续多个空格:

StringBuilder sb = new StringBuilder();
bool previousWasSpace = true;
char? firstLetterOfWord = null;
foreach (char c in str)
{
    if ((c >= 'a' && c <= 'z') || c == '_')
    {
        if (firstLetterOfWord != null)
        {
            sb.Append(firstLetterOfWord).Append(c);
            firstLetterOfWord = null;
            previousWasSpace = false;
        }
        else if (previousWasSpace)
        {
            firstLetterOfWord = c;
        }
        else
        {
            sb.Append(c);
        }
    }
    else
    {
        firstLetterOfWord = null;
        if (!previousWasSpace)
        {
            sb.Append(' ');
            previousWasSpace = true;
        }
    }
}

Console.WriteLine(sb.ToString());