0

我有一个关于阅读文本文件的问题,因为我不知道我的想法是否正确。我想从特定的字符串读取到特定的字符。

我的文字看起来像这样:

... 
...
CM_ "Hello, how are you?

Rules: Don't smoke!
      - love others

End";
...
CM_ "Why you?";
...// Many CM_
...

拆分后应如下所示:

1. CM_
2. "Hello, how are you?

    Rules: Don't smoke!
      - love others

    End"
3. CM_
4. "Why you?"
... // many CM_

我想从"CM_"直到读";"

到目前为止我尝试过的代码:

StreamReader fin = new StreamReader("text.txt");
string tmp = "";
tmp = fin.ReadToEnd();

if (tmp.StartsWith("CM_ ") && tmp.EndWith(";"))
{
var result = tmp.Split(new[] { '"' }).SelectMany((s, i) =>
                    {
                        if (i % 2 == 1) return new[] { s };
                        return s.Split(new[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
                    }).ToList();
}
foreach (string x in result)
{
   Console.WriteLine(x);
}
4

5 回答 5

1
    static void PRegex()
    {
        using (StreamReader fin = new StreamReader("text.txt"))
        {
            string tmp = fin.ReadToEnd();

            var matches = Regex.Matches(tmp, "(CM_) ([^;]*);", RegexOptions.Singleline);
            for (int i = 0; i < matches.Count; i++)
                if (matches[i].Groups.Count == 3)
                    Console.WriteLine((2 * i + 1).ToString() + ". " + matches[i].Groups[1].Value + "\r\n" + (2 * (i + 1)).ToString() + ". " + matches[i].Groups[2].Value);
        }

        Console.ReadLine();
    }

    static void PLineByLine()
    {
        using (StreamReader fin = new StreamReader("text.txt"))
        {
            int index = 0;
            string line = null;
            string currentCMBlock = null;
            bool endOfBlock = true;
            while ((line = fin.ReadLine()) != null)
            {
                bool endOfLine = false;
                while (!endOfLine)
                {
                    if (endOfBlock)
                    {
                        int startIndex = line.IndexOf("CM_ ");
                        if (startIndex == -1)
                        {
                            endOfLine = true;
                            continue;
                        }
                        line = line.Substring(startIndex + 4, line.Length - startIndex - 4);
                        endOfBlock = false;
                    }

                    if (!endOfBlock)
                    {
                        int startIndex = line.IndexOf(";");
                        if (startIndex == -1)
                        {
                            currentCMBlock += line + "\r\n";
                            endOfLine = true;
                            continue;
                        }
                        currentCMBlock += line.Substring(0, startIndex);
                        if (!string.IsNullOrEmpty(currentCMBlock))
                            Console.WriteLine((++index) + ". CM_\r\n" + (++index) + ". " + currentCMBlock);
                        currentCMBlock = null;
                        line = line.Substring(startIndex + 1, line.Length - startIndex - 1);
                        endOfBlock = true;
                    }
                }
            }
        }

        Console.ReadLine();
    }
于 2012-10-25T09:04:25.017 回答
0

您正在将整个文件读入 tmp。因此,如果“CM_”之前有任何文本,则不会输入您的条件语句。

相反,请尝试使用 fin.ReadLine 在所有行的循环中逐行读取。

于 2012-10-25T08:42:22.957 回答
0

阅读整个文件:

string FileToRead = File.ReadAllText("Path");

string GetContent(string StartAt, string EndAt, bool LastIndex)
{
string ReturnVal;

if(LastIndex)
{
ReturnVal = FileToRead.Remove(FileToRead.IndexOf(StartAt), FileToRead.IndexOf(EndAt));
Return ReturnVal;
}
else
{ 
ReturnVal = FileToRead.Remove(FileToRead.LastIndex(StartAt), FileToRead.LastIndex(EndAt));
Return ReturnVal;
}
}

-希望我在这里没有做错任何事。(自由打字)

您阅读了文件,我们删除了第一个索引前面的所有内容。以及所有之后。您可以设置它是否会返回找到的第一个结果。或最后一个。

注意:我认为使用 StringReader 会更好。(如果我没记错的话……)如果您要考虑应用程序的内存使用情况。

于 2012-10-25T08:48:08.743 回答
0

试过别的,不知道好不好 它仍然读取第一行,不知道我在这里做错了

我的代码:

        while ((tmp = fin.ReadLine()) != null)
        {
            if (tmp.StartsWith("CM_ "))
            {

                //string[] tmpList = tmp.Split(new Char[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
                var result = tmp.Split(new[] { '"' }).SelectMany((s, i) =>
                {
                    if (i % 2 == 1) return new[] { s };
                    return s.Split(new[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
                }).ToList();

                if (tmp.EndsWith(";")) break;

                fin.ReadLine();

                if (tmp.EndsWith(";"))
                {
                    result.ToList();
                    break;
                }
                else
                {
                    result.ToList();
                    fin.ReadLine();
                }

                foreach (string x in result)
                {
                    Console.WriteLine(x);
                }
            } 
于 2012-10-25T09:00:57.533 回答
0

我建议您考虑使用正则表达式。它可能正是您所需要的,并且比 Split() 灵活得多。

于 2012-10-25T11:23:47.297 回答