Чтение текстового файла и получение строки со значениями даты - PullRequest
5 голосов
/ 21 марта 2019

Есть ли простой способ найти строки, состоящие из даты и времени.

Пока что я могу прочитать текстовый файл, и мой следующий шаг - разобрать его, но перед этим я думаю, что мне нужно некоторое руководство, прежде чем я продолжу. Вот мой текущий скрипт чтения:

List<string> Temp = new List<string>();            
string[] filePaths = Directory.GetFiles(@"C:\\Temp\\", "*.txt");

foreach (string files in filePaths)
{
    var fileStream = new FileStream(files, FileMode.Open, FileAccess.Read);
    using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
    {
        Temp.Add(streamReader.ReadToEnd());
    }
}

foreach (string i in Temp)
{
    if (i.Contains("Events"))
    {
        Console.WriteLine(i);        
    }
}

Вот пример текстового шаблона, который мне нужно проанализировать, сгенерированный из инструмента.

"[Output]"
"[Events]"
"Time"  "Duration"  "Severity"  "Event" "Text1" "Text2"


"[Acquisition Settings_1]"
"Data Set"  "DataSet1"
"Data Stream"   "Data"


"[Scan Data (Pressures in Torr)]"
"Time"  "Scan"  "Mass 1"    "Mass 2"    "Mass 3"    
"10/25/2018 4:59:27 PM" 1   5.5816e-008 1.3141e-008 -1.6109e-010    
"10/25/2018 4:59:35 PM" 2   5.5484e-008 1.3403e-008 6.9720e-010 
"10/25/2018 4:59:41 PM" 3   5.5633e-008 1.3388e-008 8.8094e-011 
"10/25/2018 4:59:48 PM" 4   5.7289e-008 1.2343e-008 1.4095e-010 
"10/25/2018 4:59:54 PM" 5   5.2841e-008 1.3219e-008 7.5257e-010 

"10/25/2018 4:59:57 PM" "After Calibration due to marginal data of daily pm3 rga checking"  
"10/25/2018 5:49:51 PM" "RGA Base Pressure
Flat pallet (2018-10-25_011_a1a)"   
"10/25/2018 6:21:53 PM" "PM3 SiNFILL_27A
2018-10-25_011_A4A" 
"10/25/2018 9:51:29 PM" "IBE1 STEP
FULL TAPE
NO PRE-BAKE"    
"10/25/2018 9:58:48 PM" "IBE2 STEP

А вот моя цель или ожидаемый результат - получить строку со значением datetime:

"10/25/2018 4:59:27 PM" 1   5.5816e-008 1.3141e-008 -1.6109e-010    
"10/25/2018 4:59:35 PM" 2   5.5484e-008 1.3403e-008 6.9720e-010 
"10/25/2018 4:59:41 PM" 3   5.5633e-008 1.3388e-008 8.8094e-011 
"10/25/2018 4:59:48 PM" 4   5.7289e-008 1.2343e-008 1.4095e-010 
"10/25/2018 4:59:54 PM" 5   5.2841e-008 1.3219e-008 7.5257e-010 

Любое предложение TIA.

1 Ответ

1 голос
/ 21 марта 2019

Вы могли бы (неуверенно) сойтись с чем-то вроде этого Pattern . Он учитывает отрицательное значение Расширенная запись , а также содержит вкладки в исходном формате (не показан в примере)

^""\d+/\d+/\d+ \d+:\d+:\d+ (AM|PM)""\s+-?\d+\s+\d+.?\d+e-\d+

* Примечание : я не собираюсь писать объяснение регулярному выражению, поскольку оно слишком длинное

Пример

var pattern = @"^""\d+/\d+/\d+ \d+:\d+:\d+ (AM|PM)""\s+-?\d+\s+\d+.?\d+e-\d+";
var regex = new Regex(pattern, RegexOptions.Compiled);

var filePaths = Directory.GetFiles(@"C:\Temp", "*.txt");

var results = new List<string>();

foreach (var file in filePaths)
{
   var lines = File.ReadLines(@"D:\sample.txt").Where(x => regex.IsMatch(x));
   results.AddRange(lines);
}

Однако, чтобы сделать этот шаг дальше, вы можете сделать следующее. Это поместит все данные, проанализированные в класс.

С учетом

public class ScanData
{
   public DateTime Time { get; set; }
   public int Scan { get; set; }
   public decimal?[] MassResults  { get; set; }

   public static ScanData FromString(string data)
   {
      var split = data.Split('\t');

      decimal? Local(string value)
      {
         return decimal.TryParse(value, NumberStyles.Float, null, out var output) ? output : (decimal?)null;
      }

      var scanData = new ScanData()
                     {
                        Time = DateTime.ParseExact(split[0].Trim('"'), "M/d/yyyy h:m:s tt", null),
                        Scan = int.Parse(split[1]),
                        MassResults = split.Skip(2).Select(Local).ToArray()
                     };

      return scanData;
   }

}

* * Пример тысячи двадцать-шести * 1 028 *

var pattern = @"^""\d+/\d+/\d+ \d+:\d+:\d+ (AM|PM)""\s+-?\d+\s+\d+.?\d+e-\d+";
var regex = new Regex(pattern, RegexOptions.Compiled);

var filePaths = Directory.GetFiles(@"C:\Temp", "*.txt");

var results = new List<ScanData>();

foreach (var file in filePaths)
{
   var lines = File.ReadLines(@"D:\sample.txt")
                   .Where(x => regex.IsMatch(x))
                   .Select(x => ScanData.FromString(x));
   results.AddRange(lines);
}
...