none
Парсинг многострочного текстового файла - C# RRS feed

  • Вопрос

  • Добрый день!

    Имеется следующая проблема - у меня есть текстовый файл, в котором есть некие разделы, например:

    Тип продукта: [тут какой-то текст в несколько абзацев]

    Состав продукта: [тоже какой-то текст]

    ...

    Похожие продукты: [текст в несколько абзацев]

    И так далее, нужно распарсить этот текст по заголовкам, т.е. как раз по ключевым фразам типа "Тип продукта", "Состав продукта" и так далее. Файл многострочный естественно. Пробовал считать весь файл, потом искать по нему с помощью регулярных выражений, однако выделить целиком всю часть между заголовками не получается, так как файл многострочный.

    Можете подсказать направление поиска для решения поставленной задачи?

    20 ноября 2011 г. 11:57

Ответы

  • Такой способ не работает :(

    Работает.

    using System;
    using System.Text.RegularExpressions;
    
    namespace ConsoleApplication109
    {
        class Program
        {
            static void Main(string[] args)
            {
                string subjectString = @"Название продукта: 
    01472478 ""Быстров""
    
    Тип продукта: 
    Каша.блюдо из разваренных в воде (или в молоке) зёрен или крупы злаков, иногда с такими добавками как соль, сахар, приправы, молоко, фрукты и сухофрукты, варенье. Каша отличается от гарнира из сваренной крупы (зёрен или злаков) более жидкой консистенцией.
    Состав продукта: 
    1. 
    Зерна овса
    2. 
    Пшеница
    3. 
    Сахар
    4. 
    Соль
    5. 
    Сухое молоко
    
    Похожие продукты: 
    хлопья овсяные
    хлопья кукурузные
    мюсли
    ";
                Regex regex = new Regex(".+?(?=Состав продукта:|Тип продукта:|Похожие продукты:|$)",  RegexOptions.Singleline);
                var matches = regex.Matches(subjectString);
    
                int counter = 0;
                foreach (Match m in matches)
                {
                    Console.WriteLine("Часть " + counter + " :");
                    Console.WriteLine(m.Value);
                    counter++;
                }
    
                Console.ReadLine();
            }
        }
    }
    
    

    • Помечено в качестве ответа PashaPashModerator 22 ноября 2011 г. 11:55
    20 ноября 2011 г. 17:14
    Отвечающий

Все ответы

  • 	Regex regex = new Regex(".+?(?=Состав продукта:|Тип продукта:|Похожие продукты:|$)",
    		RegexOptions.Singleline);
    	Match matches = regex.Match(subjectString);
    

    20 ноября 2011 г. 13:05
    Отвечающий
  • [тут какой-то текст в несколько абзацев] - может заканчиваться и переводом каретки и окончанием строки, поэтому разбирать текст видимо нужно как-то иначе. Такой способ не работает :(
    Вот например:

     Название продукта: 
    01472478 "Быстров"
    
    Тип продукта: 
    Каша.блюдо из разваренных в воде (или в молоке) зёрен или крупы злаков, иногда с такими добавками как соль, сахар, приправы, молоко, фрукты и сухофрукты, варенье. Каша отличается от гарнира из сваренной крупы (зёрен или злаков) более жидкой консистенцией.
    Состав продукта: 
    1. 
    Зерна овса
    2. 
    Пшеница
    3. 
    Сахар
    4. 
    Соль
    5. 
    Сухое молоко
    
    Похожие продукты: 
    хлопья овсяные
    хлопья кукурузные
    мюсли
    


    Вычленить нужно текст между названием, типом, составом и похожими продуктами.

    Пока решение вижу в построчном прохождении по массиву строк.



    • Изменено sir.enmity 20 ноября 2011 г. 13:36
    20 ноября 2011 г. 13:24
  • Такой способ не работает :(

    Работает.

    using System;
    using System.Text.RegularExpressions;
    
    namespace ConsoleApplication109
    {
        class Program
        {
            static void Main(string[] args)
            {
                string subjectString = @"Название продукта: 
    01472478 ""Быстров""
    
    Тип продукта: 
    Каша.блюдо из разваренных в воде (или в молоке) зёрен или крупы злаков, иногда с такими добавками как соль, сахар, приправы, молоко, фрукты и сухофрукты, варенье. Каша отличается от гарнира из сваренной крупы (зёрен или злаков) более жидкой консистенцией.
    Состав продукта: 
    1. 
    Зерна овса
    2. 
    Пшеница
    3. 
    Сахар
    4. 
    Соль
    5. 
    Сухое молоко
    
    Похожие продукты: 
    хлопья овсяные
    хлопья кукурузные
    мюсли
    ";
                Regex regex = new Regex(".+?(?=Состав продукта:|Тип продукта:|Похожие продукты:|$)",  RegexOptions.Singleline);
                var matches = regex.Matches(subjectString);
    
                int counter = 0;
                foreach (Match m in matches)
                {
                    Console.WriteLine("Часть " + counter + " :");
                    Console.WriteLine(m.Value);
                    counter++;
                }
    
                Console.ReadLine();
            }
        }
    }
    
    

    • Помечено в качестве ответа PashaPashModerator 22 ноября 2011 г. 11:55
    20 ноября 2011 г. 17:14
    Отвечающий
  • > текстовый файл, в котором есть некие разделы [...] нужно распарсить этот текст по заголовкам [...] выделить целиком всю часть между заголовками


     
    работает с файлами любого размера, т.к. не загружает файл целиком; можно фильтровать строки во время загрузки ...

     

    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    ...
    foreach (var b in Block.Load("test.txt"))
    {
        var str = b.Title + "\n\t" + string.Join("\n\t", b.Body);
        System.Diagnostics.Trace.WriteLine(str);
    }
    ...
    class Block
    {
        public string Title;
        public IList<string> Body;
    
        public static IEnumerable<Block> Load(string path)
        {
            Block ret = null;
            foreach (var line in File.ReadLines(path).Select(l => l.Trim()))
            {
                if (line.Length == 0 && ret != null)
                {
                    yield return ret;
                    ret = null;
                    continue;
                }
    
                if (line.EndsWith(":"))
                {
                    ret = new Block { Title = line.TrimEnd(':'), Body = new List<string>() };
                    continue;
                }
    
                if (ret != null)
                    ret.Body.Add(line);
            }
        }
    }
    
      
    • Изменено Malobukv 20 ноября 2011 г. 18:42
    • Предложено в качестве ответа Malobukv 21 ноября 2011 г. 16:52
    20 ноября 2011 г. 18:40
  • Спасибо большое, разобрался, почему не работало.

    21 ноября 2011 г. 15:51