0

I've got an ini file I'm reading in and I'm trying to read the lines between certain strings. In this instance, I'm trying to get the lines 1=One, 2=Two, 3=Three between the section headers [SECTION1],[SECTION2]. The amount of lines between the two sections can be variable and so I'm trying to create a list and then cycle through that while still reading the file. I then need to create and append these to an XDocument which will be saved on disk.

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

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

The code I have for it right now is here:

        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

But I can't seem to figure out how to cycle through the lines in the middle and get the lines themselves. I can split it after that but I can't seem to figure out how to get the lines in the middle.

Jawad
  • 11,028
  • 3
  • 24
  • 37
camelCase
  • 1
  • 1
  • Does this help you? https://stackoverflow.com/questions/217902/reading-writing-an-ini-file –  Jan 09 '20 at 19:20

1 Answers1

0

It can be done simply by first finding the indexes of the sections, and then calculating the sections lengths by simple index substraction. With these informations, it is then easy to filter the needed lines.

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"

You can then use the result to construct easily your XML. If you need to keep the name of the sections, the last code block can be replaced by:

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") }
Laurent Gabiot
  • 1,251
  • 9
  • 15