首页 > 解决方案 > 读取 2 个唯一字符串之间的行,将它们附加到 XDocument

问题描述

我有一个正在读取的 ini 文件,我正在尝试读取某些字符串之间的行。在这种情况下,我试图在节标题 [SECTION1]、[SECTION2] 之间获取行 1=One、2=Two、3=Three。两个部分之间的行数可以是可变的,因此我尝试创建一个列表,然后在读取文件的同时循环遍历该列表。然后我需要创建这些内容并将其附加到将保存在磁盘上的 XDocument。

[SECTION1]
1=One
2=Two
3=Three

[SECTION2]
4=Four
5=Five
6=Six

我现在拥有的代码在这里:

        var lines = File.ReadAllLines(file);
        List<XElement> iniValues = null;
        string correctPath = null;
        foreach (var line in lines)
                    {
                        if (Regex.IsMatch(line, @"\[(.*?)\]"))
                        {
                            Console.WriteLine(line);
                            switch (line.Substring(1, line.IndexOf("]") - 1))
                            {
                            //Switch cases based off of the matching values

但我似乎无法弄清楚如何在中间的线条中循环并自己获得线条。之后我可以将其拆分,但我似乎无法弄清楚如何将线条放在中间。

标签: c#

解决方案


可以简单地通过首先找到节的索引,然后通过简单的索引减法计算节的长度来完成。有了这些信息,就可以轻松过滤所需的行。

var Lines = File.ReadAllLines(file);

// First Get the index of each section
var SectionsIndex = Lines
    .Select((l, index) => new { index, IsSection = l.StartsWith("[") }) // Instead of l.StartsWith("[") you can use any code that will match your section.
    .Where(l => l.IsSection)
    .Select(l => l.index)
    .ToList();
// => 0, 4

// Then with these indexes, calculate the index of each first content line and the length of each section
var SectionIndexAndLength = SectionsIndex
    .Zip(SectionsIndex.Append(Lines.Count).Skip(1))
    .Select(e => new {index = e.First + 1, Length = e.Second - (e.First + 1)})
    .ToList();
// => { index = 1, Length = 3} ,  { index = 5, Length = 3 }    

// Then get the corresponding lines using the above indexes and lengths.
var Result =
    SectionIndexAndLength
    .Select(e => Lines
        .Skip(e.index)
        .Take(e.Length)
        .ToList())
    .ToList();

// => "1=One", "2=Two", "3=Three" 
// => "4=Four", "5=Five", "6=Six"

然后,您可以使用结果轻松地构造您的 XML。如果您需要保留部分的名称,可以将最后一个代码块替换为:

var Result =
    SectionIndexAndLength
    .Select(e => new {
        SectionTitle = Lines[e.index - 1],
        SectionContent = Lines
        .Skip(e.index)
        .Take(e.Length)
        .ToList()
    })
    .ToList()

// => { SectionTitle = [SECTION1], SectionContent = ("1=One", "2=Two", "3=Three") }
// => { SectionTitle = [SECTION2], SectionContent = ("4=Four", "5=Five", "6=Six") }

推荐阅读