Разбор разделов HTML в c # - PullRequest
       4

Разбор разделов HTML в c #

3 голосов
/ 08 февраля 2011

Мне нужно разобрать разделы из строки HTML.Например:

<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>[section=quote]</p>
<p>Mauris at turpis nec dolor bibendum sollicitudin ac quis neque.</p>
<p>[/section]</p>

При анализе секции цитаты должно получиться:

<p>Mauris at turpis nec dolor bibendum sollicitudin ac quis neque.</p>

В настоящее время я использую регулярное выражение для захвата содержимого внутри [section = quote] ... [/ section], но поскольку разделы вводятся с помощью редактора WYSIWYG, сами теги разделов оборачиваются тегом абзаца, поэтому результат анализа:

</p>
<p>Mauris at turpis nec dolor bibendum sollicitudin ac quis neque.</p>
<p>

Используемое мной в настоящее время регулярное выражение::

\[section=(.+?)\](.+?)\[/section\]

И я также делаю некоторую дополнительную очистку перед синтаксическим анализом разделов:

protected string CleanHtml(string input) {
    // remove whitespace
    input = Regex.Replace(input, @"\s*(<[^>]+>)\s*", "$1", RegexOptions.Singleline);
    // remove empty p elements
    input = Regex.Replace(input, @"<p\s*/>|<p>\s*</p>", string.Empty);
    return input;
}

Может ли кто-нибудь предоставить регулярное выражение, которое достигнет того, что я ищуЯ трачу свое время, пытаясь сделать это с Regex?Я видел ссылки на Html Agility Pack - было бы лучше для чего-то подобного?

[Обновить]

Благодаря Оскару я использовал комбинацию HTML Agility Pack и Regexразобрать разделы.Это все еще нужно немного доработать, но это почти там.

public void ParseSections(string content)
{
    this.SourceContent = content;
    this.NonSectionedContent = content;

    content = CleanHtml(content);

    if (!sectionRegex.IsMatch(content))
        return;

    var doc = new HtmlDocument();
    doc.LoadHtml(content);

    bool flag = false;
    string sectionName = string.Empty;
    var sectionContent = new StringBuilder();
    var unsectioned = new StringBuilder();

    foreach (var n in doc.DocumentNode.SelectNodes("//p")) {               
        if (startSectionRegex.IsMatch(n.InnerText)) { 
            flag = true;
            sectionName = startSectionRegex.Match(n.InnerText).Groups[1].Value.ToLowerInvariant();
            continue;
        }
        if (endSectionRegex.IsMatch(n.InnerText)) {
            flag = false;
            this.Sections.Add(sectionName, sectionContent.ToString());
            sectionContent.Clear();
            continue;
        }

        if (flag)
            sectionContent.Append(n.OuterHtml);
        else
            unsectioned.Append(n.OuterHtml);
    }

    this.NonSectionedContent = unsectioned.ToString();
}

Ответы [ 2 ]

2 голосов
/ 17 февраля 2011

Следующие работы с использованием библиотеки HtmlAgilityPack:

using HtmlAgilityPack;

...

HtmlDocument doc = new HtmlDocument();
doc.Load(@"C:\file.html");


bool flag = false;
var sb = new StringBuilder();
foreach (var n in doc.DocumentNode.SelectNodes("//p"))
{
    switch (n.InnerText)
    {
        case "[section=quote]":
            flag = true;
            continue;
        case "[/section]":
            flag = false;
            break;
    }
    if (flag)
    {
        sb.AppendLine(n.OuterHtml);
    }
}

Console.Write(sb);
Console.ReadLine();

Если вы просто хотите напечатать Mauris at turpis nec dolor bibendum sollicitudin ac quis neque. без <p>...</p>, вы можете заменить n.OuterHtml на n.InnerHtml.

Конечно, вы должны проверить, является ли doc.DocumentNode.SelectNodes("//p") null.
Если вы хотите загрузить html из онлайн-источника вместо файла, вы можете сделать:

var htmlWeb = new HtmlWeb();  
var doc = htmlWeb.Load("http://..../page.html");

Edit:

Если [section=quote] и [/section] могут быть внутри любого тега (не всегда <p>), вы можете заменить doc.DocumentNode.SelectNodes("//p") на doc.DocumentNode.SelectNodes("//*").

1 голос
/ 08 февраля 2011

Как насчет замены

<p>[section=quote]</p>

с

[section=quote]

и

<p>[/section]</p>

с

[/section]

как часть вашей уборки. Затем вы можете использовать существующее регулярное выражение.

...