Страницы

Поиск по вопросам

вторник, 28 января 2020 г.

Помогите распарсить файл в C#

#c_sharp


Есть файл с содержанием:

completed...
Database: localhost_students
+----------------------------+---------+
| Tabl                       |  Rows   |
+----------------------------+---------+
| faculty_data               |  2429   |
| address_data               |  1674   |
| scholarship_data           |  1460   |
+----------------------------+---------+


Цель выдернуть и скормить в массив/колекцию только эту часть данных без cмвола"|"
с разделителями ",":

| faculty_data               |  2429   |
| address_data               |  1674   |
| scholarship_data           |  1460   |


Помогите пожалуйста составить правильную регулярку...
    


Ответы

Ответ 1



Не стреляйте из пушки по воробьям, не нужны здесь регулярки public Dictionary Execute(string filename) { var content = File.ReadAllLines(filename); var result = new Dictionary(); foreach (var line in content) { var spl = line.Split('|'); if (spl.Length == 4 && !string.Equals(spl[1].Trim(), "Tabl")) result.Add(spl[1].Trim(), spl[2].Trim()); } return result; } Основа -- string.Split. Этот метод ещё проще, чем указанный @ixSci - нет нужны искать начало фрагмента и конец, мы просто отбрасываем все строки, которые не имеют формата | что-то | что-то ещё |, дополнительно нужно лишь выкинуть шапку таблицы. Разумеется, мы при этом рассчитываем, что один файл содержит только одну таблицу - если не так, то нужно ловить начало-конец каждого фрагмента. PS Опционально: Dictionary, List и т.п.

Ответ 2



Сильно не пинайтесь, некогда было делать с подсчетом вхождений, сделал с регуляркой просто чтобы помочь человеку: private void ParseText() { var list = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "text.txt").Split('\n').ToList(); var resultList = new List(); foreach (var line in list) { if (line.Contains("| ") && !line.Contains("+")) { var temp = line.Replace(" | ", ",").Replace("|", "").Split(','); if (new Regex(@"^[0-9]+$").IsMatch(temp[1].Trim())) { var resultLine = temp[0].Trim() + "," + temp[1].Trim(); if (!resultList.Contains(resultLine)) resultList.Add(resultLine); } } } MessageBox.Show(string.Join("\r\n", resultList)); }

Ответ 3



Например, можно так, просто и лаконично: public TableInfo[] ParseTableInfo(string fileName) { var content = File.ReadAllText(fileName); var data = Regex.Matches(content, @"^\|\s*(?[^\s|]+)\s*\|\s*(?\d+)\s*\|\r?$", RegexOptions.Multiline) .Cast() .Select(m => new { Table = m.Groups["tabl"].Value, Rows = int.Parse(m.Groups["rows"].Value) }); return data.ToArray(); } И потом использовать этот метод в коде: var data = ParseTableInfo("<путь_к_файлу>"); foreach(var item in data) Console.WriteLine("Table {0} have {1} rows", item.Table, item.Row); Сам тип TableInfo очень прост: public class TableInfo { public string Table { get; set; } public int Rows { get; set; } } Если файл большой (десятки МБ и больше), можно не грузить все в память разом методом File.ReadAllText, и не парсить все эти мегабайты единой операцией, а читать файл построчно, например - с помощью StreamReader.ReadLine, и парсить этой же регуляркой уже строки по отдельности. Только флаг RegexOptions.Multiline указывать уже не надо в этом случае. По поводу парса имени таблицы небольшое замечание. Я не знаю, какие в данном случае возможны варианты именования, поэтому исходил из того, что вайтспейс или | будет означать окончание имени. Зная больше о возможных именованиях можно составить более подходящий парс имени таблицы.

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

Отправить комментарий