[英]Regex with multiple matches: pattern should delimit old and start new match
我有一段類似於以下內容的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>
分隔上一個匹配項可以正常工作。 但是我需要在下一場比賽中已經有相同的文本。 但是,它不是“回收的”。 一旦這段文字已用於界定舊的比賽,它將不再被用於開始新的比賽。
有任何想法嗎?
不要使用正則表達式來解析HTML 。請使用一些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" ]
]
如果您想使用REGEX,請使用C#中的Multiline Regex
匹配選項嘗試這一點。
(<p>Header</p>[\s\S]*?)(?=<p>Header</p>|\Z)
這是使用lookahead (?=...)
檢查匹配項后是否跟隨標簽<p>Header</p>
還是在輸入\\Z
的末尾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.