编程语言
首页 > 编程语言> > 在C#中解析HTML部分

在C#中解析HTML部分

作者:互联网

我需要从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编辑器输入了这些部分,所以section标记本身被包裹在一个段落标记中,因此解析结果为:

</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的引用-这样会更好吗?

[更新]

感谢Oscar,我使用了HTML Agility包和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();
}

解决方法:

使用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();

如果您只想打印
毛里斯在没有头饰的双本比勒索比利丁素qui neque.如果不使用< p ......< / p&gt ;,则可以将n.OuterHtml替换为n.InnerHtml. 当然,您应该检查doc.DocumentNode.SelectNodes(“ // p”)是否为空.
如果要从在线源而不是文件加载html,可以执行以下操作:

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

编辑:

如果[section = quote]一个[/ section]可以在任何标签内(并不总是< p>),则可以将doc.DocumentNode.SelectNodes(“ // p”)替换为doc.DocumentNode.SelectNodes(“ // *“).

标签:html-agility-pack,html-parsing,c,regex
来源: https://codeday.me/bug/20191208/2093707.html