簡體   English   中英

正則表達式具有多個匹配項:模式應分隔舊匹配項並開始新匹配項

[英]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的末尾。

如果它在語法上是正確的XML(意味着它不違反XML的最小結構規則),則可以將其簡單地加載到Xmldocument並使用XPath表達式提取所需的位,或者使用XSLT轉換來獲取所需的內容。

為什么要重新發明輪子?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM