Чтение определенных частей файла

#c# #linq

#c# #linq

Вопрос:

У меня есть файл, который структурирован как:

 [REG]
1
2
3

[LAP]
4
5
6

  

Я просто хочу прочитать строки под [REG] частью, затем я изменю код при чтении [LAP] части, но следующий код только возвращает меня [REG]

 string[] commands = File.ReadLines(@"Engines"   url_engine_code)
    .TakeWhile(x => x.TrimStart().StartsWith("[REG]"))
    .SkipWhile(x => x.TrimStart().StartsWith("[LAP]"))
    .ToArray();

foreach (var action in commands) 
{
    Helpers.ReturnMessage(action);
}
  

Я что-то упускаю? мой LINQ не самый лучший! спасибо за любую помощь, это ценится.

Комментарии:

1. LINQ не очень хорошо подходит для работы с последовательными связями между объектами в IEnumerable. Это можно сделать (как показывают ответы здесь), но это довольно сложно и, скорее всего, предполагает многократное чтение файла.

Ответ №1:

Вам просто нужно отменить TakeWhile тест (мне нравится это называть SkipUntil ), а затем использовать обычный TakeWhile :

 var ans = File.ReadLines(@"Engines"   url_engine_code)
             .SkipWhile(s => !s.TrimStart().StartsWith("[REG]")) // find line with [REG]
             .Skip(1) // skip line with [REG]
             .TakeWhile(s => !s.TrimStart().StartsWith("[LAP]"))
             .Where(s => s.Trim() != String.Empty)
             .ToList();
             
var ans2 = File.ReadLines(@"Engines"   url_engine_code)
             .SkipWhile(s => !s.TrimStart().StartsWith("[LAP]")) // find line with [LAP]
             .Skip(1) // skip line with [LAP]
             .Where(s => s.Trim() != String.Empty)
             .ToList();
  

Ответ №2:

Вы говорите, что вам нужно читать только строки, которые начинаются с [REG] -> .TakeWhile(x => x.TrimStart().StartsWith("[REG]")) строки после [REG] , но до [LAP] , но ни одна из этих строк не начинается с текста [REG] . Попробуйте:

 string[] commands = File.ReadLines(@"Engines"   url_engine_code)
      .Skip(1) //Skip the first line [REG]
      .TakeWhile(x => !x.TrimStart().StartsWith("[LAP]") amp;amp;
        !String.IsNullOrWhiteSpace(x)) //Take while not the line which start with [LAP] and is not blank (empty)
      .ToArray();
  

В обратном порядке читайте, пока не дойдете до [LAP] :

 string[] commands = File.ReadAllLines(@"C:test.txt").Reverse()
                     .TakeWhile(x => !x.TrimStart().StartsWith("[LAP]"))
                     .Where(x => !string.IsNullOrWhiteSpace(x))
                     .ToArray();
  

Ответ №3:

Вот документация для takeWhile: https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable .takewhile?view=net-5.0

Я рекомендую всегда читать документацию из MSDN для .NET, она все очень хорошо объясняет.

Метод takeWhile принимает перечисляемые и продолжает возвращать элементы, пока указанное условие истинно. Эта строка кода:

 .TakeWhile(x => x.TrimStart().StartsWith("[REG]"))
  

таким образом, будет продолжать возвращать вам строки до тех пор, пока они начинаются с [REG] . Он выдаст вам только первую строку, а затем вернет.