#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 DictionaryExecute(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 указывать уже не надо в этом случае. По поводу парса имени таблицы небольшое замечание. Я не знаю, какие в данном случае возможны варианты именования, поэтому исходил из того, что вайтспейс или | будет означать окончание имени. Зная больше о возможных именованиях можно составить более подходящий парс имени таблицы.
Комментариев нет:
Отправить комментарий