【发布时间】:2011-06-23 08:06:24
【问题描述】:
我需要从 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] 中的内容,但由于这些部分是使用所见即所得编辑器输入的,因此部分标签本身会被包裹在一个段落标签中,所以解析结果为:
</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;
}
谁能提供一个正则表达式来实现我正在寻找的东西,或者我是否在浪费时间尝试使用正则表达式来做到这一点?我看到了对 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();
}
【问题讨论】:
-
用正则表达式解析 html 通常是个坏主意,因为 html 不规则。如果你可以看一下 html 解析器,它们有很多可用的,它们会带来更少的痛苦。
标签: c# regex html-parsing html-agility-pack