0

Здравствуйте!
Подскажите, пожалуйста, как спарсить строку из html файла такого вида, с помощью regexp:

<div> <h2> <span style="font-size: 12px; padding: 5px;">Hello!</span></h2> "variable string" <br /><br /> </div>

Под "variable string" предполагается какой-то текст произвольный (имя если быть точным).

myHttpResponse = (HttpWebResponse)myHttpRequest.GetResponse();
        using (var readers = new StreamReader(myHttpResponse.GetResponseStream()))
            {
                // сайт-строка
                string html = readers.ReadToEnd();

Мой вариант реализации слишком "индусирован": сплитом разбиваю строку на массив строк без "лишних" символов, индентифицирую элемент содержащий "Hello!", по его номеру определяю номер следующего элемента (имя) и его уже вывожу. Есть ещё кончено html agility pack для парсинга html в c#, но интересует именно регулярное выражение, т.к. с его помощью можно не тянуть целую библиотеку для пары строчек кода.

Задачу решил с помощью регулярного выражения (в комментарии ниже), но вот пример моего "парсинга", он более наглядный для начинающих вроде меня.


        // Строка для хранения результата
        string storageForResponse = "";
        // Читаем HTML-код сайта
        string html = readers.ReadToEnd();
        // Разбиваем строку на массив строк
        string[] words = html.Split(new[] { ' ', ',', ':', '?', '\n', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries);
    for (int i = 0; i &lt; words.Length; i++)
    {
    if (words[i] == "Hello!")
    {
    if (i &lt; words.Length - 1)
    {
    storageForResponse += words[i + 1];
    }
    break;
    }
    }
    }

  • @grandpa а что случится страшного, если библиотеку все-таки подтянуть? – etki Aug 17 '14 at 21:26
  • Думаю что ничего, но не представляю как с её помощью выцепить именно этот фрагмент (
    тег без какого либо уникального имени)
    –  Aug 17 '14 at 21:35
  • 3
    Была у программиста проблема. Решил он её с помощью регулярных выражений. Теперь у него две проблемы. © – Donil Aug 18 '14 at 02:48

2 Answers2

6

HTML не парсится регулярными выражениями. В принципе. Пользуйтесь полновесным парсером. Если есть сомнения, подумайте, как вы собираетесь обрабатывать, например, комментарии. HTML entity. Незначимые пробелы. Вложенные теги. Вот внеклассное чтение по теме.

VladD
  • 206,799
  • @VladD, как всегда, отличное "внеклассное чтение".

    А может и правда, что от популярности регулярок один лишь вред?

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

    – avp Aug 18 '14 at 09:32
  • 3
    @avp: Я считаю, что регулярки переоценены. Ну и вспомню ещё раз цитату jwz, которую привёл выше @Donil.

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

    – VladD Aug 18 '14 at 11:07
3

Если нужно спарсить много данных из HTML\не получается вытянуть регулярками и нужен парсинг по DOM модели - то однозначно: https://htmlagilitypack.codeplex.com/

Если дернуть нужно одну строчку - не вижу смысла подтягивать либу. Вот пример регулярки для выдергивания всех значений со страницы между тегами:

    using System.Text.RegularExpressions;
        // Регулярка
        string pattern = @"&lt;div class=""date""&gt;(?&lt;val&gt;.*?)&lt;\/span&gt;";
        RegexOptions options = RegexOptions.Compiled | RegexOptions.Singleline;
        Regex regex = new Regex(pattern, options);
        Match match = regex.Match(HTML.ToString());
        string Result = "";

        while (match.Success)
        {
            result += match.Groups["val"].Value;
            match = match.NextMatch();
        }

Alexis
  • 3,476
  • 1

    то однозначно: https://htmlagilitypack.codeplex.com/

    Я бы поспорил. CsQuery тоже хорош. И селекторы у него читабельнее и короче

    – Donil Aug 18 '14 at 08:29
  • Да, возможно, но htmlagilitypack есть и под WinRT - а это несомненный плюс. – Alexis Aug 18 '14 at 08:31
  • Спасибо за пример регулярки, использую как шаблон в дальнейшем, задачу решил без регулярок и библиотек, всё таки "индусский" метод оказался наиболее подходящим. –  Aug 18 '14 at 20:40
  • 1
    Если будете пользоваться регулярками - сначала выводите разметку в richTextBox, у меня бывали случаи, когда через браузер стояли двойные кавычки, а get запросом - одинарные. – Alexis Aug 19 '14 at 07:18