#c# #readfile
#c# #readfile
Вопрос:
Есть ли простой способ найти строки, состоящие из даты и времени.
Пока я могу прочитать текстовый файл, и мой следующий шаг — разобрать его, но перед этим, я думаю, мне нужно некоторое руководство, прежде чем я продолжу. Вот мой текущий сценарий чтения:
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. (A) Что
streamReader.ReadToEnd()
делает? (Проверьте свои предположения, заглянув в документацию для StreamReader.ReadToEnd / TextReader.ReadToEnd) (B). Посмотрите, какие методы предоставляетSystem.IO.File
класс (опять же, документация для этого класса даст вам обзор, а также подробную информацию о предоставляемых методах). Некоторые из них могут быть полезны для упрощения вашего кода. (C) Для обработки отдельных строк ознакомьтесь с тем, как вы можете определять строки даты и времени или когда они начинаются и заканчиваются (вы можете выполнять простые сравнения / нахождение строк или пытаться использовать сопоставление шаблонов строк с регулярными выражениями)2. кажется, если вы разделите с помощью («) символа, вы можете получить строку формы даты в строке[1] . попробуйте / catch проанализировать как дату. если это успешно, сохраните во временной строке всю строку.
Ответ №1:
Вероятно, вы могли бы (ориентировочно) обойтись чем-то вроде этого шаблона. Он учитывает отрицательную расширенную нотацию, а также имеет вкладки в исходном формате (не показан в примере)
^""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;
}
}
Пример
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);
}
Комментарии:
1. Должен ли я сохранять это в виде строки в цикле чтения? Я не вижу никаких выходных данных из моего. Это потому, что я добавляю их в список, а затем зацикливаю его.
2. @Rockn’Roll привет, я не совсем уверен, о чем вы спрашиваете, однако я обновил пример, более соответствующий тому, что вы делаете.
3. Я попробовал предложенный вами код, но список возвращает мне систему. Коллекции. Generic.List`1[Система. Строка].
4. и если я собираюсь зациклить temp, это ничего мне не возвращает
5. могу ли я предоставить вам фактический текстовый файл? размер текстового файла составляет 102 мб. Я просто упрощаю свой образец содержимого, чтобы он соответствовал моему вопросу.