简体   繁体   English

如何在c#中从文件中读取文本从一个值到另一个值

[英]How to read text from file from one value to other in c#

I`m new in c#, I'm still learning that language.我是 C# 新手,我还在学习那门语言。 Now I try to make app which read text and to my data i need only specific lines.现在我尝试制作读取文本和数据的应用程序,我只需要特定的行。 Text look like:文字看起来像:

[HAEDING]
Some value

[HEADING]
Some other value

[HEADING]
Some other text
and continuation of this text in new line

[HEADING]
Last text

I try to write method which read text and put it into string[] by split it like this:我尝试编写读取文本并将其放入 string[] 的方法,方法如下:

string[0] = Some value
string[1] = Some other value
string[2] = Some other text and continuation of this text in new line
string[3] = Last text

So I want to read line from value [HEADING] to value new line which is empty.所以我想从值 [HEADING] 读取行到空的值新行。 I thought that is should write by ReadAllLines and line by line check start position on value [HEADING] and end position on empty value in new line.我认为应该由 ReadAllLines 写入并逐行检查值 [HEADING] 的起始位置和新行中空值的结束位置。 I try this code:我试试这个代码:

string s = "mystring";
int start = s.IndexOf("[HEADING]");
int end = s.IndexOf("\n", start);
string result = s.Substring(start, end - start);

but it's substring to all lines in my text not like loop between first [HEADING] and empty new line, second etc. Maybe someone can help me with this?但它是我文本中所有行的子字符串,而不是第一个 [HEADING] 和空的新行、第二个等之间的循环。也许有人可以帮我解决这个问题?

You could try to split the string by "[HEADING]" to get the strings between these lines.您可以尝试通过"[HEADING]"拆分字符串以获取这些行之间的字符串。 Then you could join each string into a single line and trim the whitespace around the strings:然后你可以将每个字符串连接成一行并修剪字符串周围的空格:

string content = @"[HEADING]
Some value

[HEADING]
Some other value

[HEADING]
Some other text
and continuation of this text in new line

[HEADING]
Last text";

var segments = content.Split(new[] { "[HEADING]"}, StringSplitOptions.RemoveEmptyEntries)  // Split into multiple strings
    .Select(p=>p.Replace("\r\n"," ").Replace("\r"," ").Replace("\n"," ").Trim()) // Join each single string into single line
    .ToArray();

Result:结果:

segments[0] = "Some value"
segments[1] = "Some other value"
segments[2] = "Some other text and continuation of this text in new line"
segments[3] = "Last text" 

Here's a solution which avoids the substring/index checking, which could potentially be fraught with errors.这是一个避免子字符串/索引检查的解决方案,这可能会充满错误。

There are answers such as this one that use LINQ, but for a newcomer to the language, basic looping is an OK place to start.有答案,比如这一个是使用LINQ,但对于初来乍到的语言,基本的循环是一个不错的开端。 Also, this is not necessarily the best solution for efficiency or whatever.此外,这不一定是效率或其他方面的最佳解决方案。

This foreach loop will handle your case, and some of the "dirty" cases.这个foreach循环将处理你的情况,以及一些“脏”的情况。

var segments = new List<string>();
bool headingChanged = false;
foreach (var line in File.ReadAllLines("somefilename.txt"))
{
    // skip blank lines
    if (string.IsNullOrWhitespace(line)) continue;

    // detect a heading
    if (line.Contains("[HEADING]")
    {
        headingChanged = true;
        continue;
    }

    if (headingChanged)
    {
        segments.Add(line);

        // this keeps us working on the same segment if there
        // are more lines to be added to the segment
        headingChanged = false;
    }
    else
    {
        segments[segments.Length - 1] += " ";
        segments[segments.Length - 1] += line;
        // you could replace the above two lines with string interpolation...
        // segments[segments.Length - 1] = $"{segments[segments.Length - 1]} {line}";
    }
}

In the above loop, the ReadAllLines obviates the need to check for \\r and \\n .在上面的循环中, ReadAllLines不需要检查\\r\\n Contains will handle [HEADING] no matter where it changes. Contains将处理[HEADING]不管它的变化。

You don't need substring, you can just compare the value s == "[HEADING]".您不需要子字符串,您只需比较值 s == "[HEADING]"。

Here's an easy to understand example:这是一个易于理解的示例:

var lines = System.IO.File.ReadAllLines(myFilePath);

var resultLines = new List<String>();

var collectedText = new List<String>();

foreach (var line in lines)
{
    if (line == "[HEADING]")
    {
        collectedText = new List<String>();
    }
    else if (line != "")
    {
        collectedText.Add(line);
    }
    else //if (line == "")
    {
        var joinedText = String.Join(" ", collectedText);
        resultLines.Add(joinedText);
    }
}

return resultLines.ToArray();

the loop does this:循环这样做:

  1. we go line by line我们一行一行地走
  2. "start collecting" (create list) when we encounter with "[HEADING]" line当我们遇到“[HEADING]”行时“开始收集”(创建列表)
  3. "collect" (add to list) line if not empty如果不为空,则“收集”(添加到列表)行
  4. "finish collecting" (concat and add to results list) when line is empty当行为空时“完成收集”(连接并添加到结果列表)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM