我有一段类似于此的HTML代码:
<p>Header</p>
<p>some text</p>
<p>some more text</p>
<p>Header</p>
<p>only one paragraph</p>
<p>Header</p>
<p>some text</p>
<p>some more text</p>
每个标题下的段落数量未知。我现在想要创建一个正则表达式模式来提取标题的所有(!)出现以及以下段落。我试过这个:(<p>Header</\p>.*?)<p>Header</\p>
。但这只适用于每一场比赛。
使用<p>Header</p>
分隔上一个匹配工作正常。但我需要在下一场比赛中获得同一段文字。但是,它不是'#34;再循环&#34;。一旦这段文字被用来划分旧的比赛,就不会再用它来开始新的比赛。
有什么想法吗?
答案 0 :(得分:2)
Don't use regular expressions for parsing HTM L。使用一些HTML解析器,如HtmlAgilityPack(可从NuGet获得)。例如。提取所有段落:
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html_string);
var paragraphs = doc.DocumentNode.SelectNodes("//p").Select(p => p.InnerText);
以下任务是简单处理字符串列表。您可以创建扩展方法以将段落序列拆分为块:
public static IEnumerable<List<T>> SplitBy<T>(
this IEnumerable<T> source, Func<T, bool> separator)
{
List<T> batch = new List<T>();
using (var iterator = source.GetEnumerator())
{
while (iterator.MoveNext())
{
if (separator(iterator.Current) && batch.Any())
{
yield return batch;
batch = new List<T>();
}
batch.Add(iterator.Current);
}
}
if (batch.Any())
yield return batch;
}
用法:
var result = paragraphs.SplitBy(p => p == "Header");
对于您的示例HTML,它会返回
[
[ "Header", "some text", "some more text" ],
[ "Header", "only one paragraph" ],
[ "Header", "some text", "some more text" ]
]
答案 1 :(得分:1)
如果您想使用REGEX,请在C#中使用Multiline Regex
匹配选项试试这个。
(<p>Header</p>[\s\S]*?)(?=<p>Header</p>|\Z)
这是使用前瞻(?=...)
进行检查,无论匹配后跟标记<p>Header</p>
还是输入结尾\Z
。
答案 2 :(得分:0)
如果它的语法正确的XML(意味着它没有违反XML的最小结构规则),您可以简单地将其加载到Xmldocument
并拉出你的位需要使用XPath expressions,或使用XSLT transform来获得您想要的内容。
为什么重新发明轮子?