簡體   English   中英

preg_match_all-正則表達式的貪婪部分,但最大程度地增加匹配數

[英]preg_match_all - greedy part of regex, but maximise number of matches

我有以下html來解析:

<h1 class="x">test</h1>
<p>some text <img src="x" /></p>

<h1 class="x1">test2</h1>
<p>some text </p>

<h1 class="2">test3</h1>
<p>some text <img src="x" /></p>

我可以將其解析為具有單個正則表達式的數組嗎?

我試過了

preg_match_all('#(<h1[^>]*?>)(.*?)(</h1>)(.*)#ism',$html,$arr);

這給我只有一個條目,因為正則表達式的最后一部分是貪婪的,並且

preg_match_all('#(<h1[^>]*?>)(.*?)(</h1>)(.*?)#ism',$html,$arr);

這給了我<h1>之間的HTML內容,因為表達式不是很貪心。

我如何才能使零件在匹配之后變得貪婪,同時又要匹配盡可能多的出現?

附加評論:

  • 這個問題是學術上的問題,我已經使用pre_split解決了該問題,並且可以使用其他多種方法,但是可能還會有缺點(例如DOM可能不適用於我無法控制的無效HTML)。 但是,這是一個反復出現的問題,我很想了解更多。

您需要某種形式的終端機。 正則表達式無法猜測,直到您要匹配哪個部分。

在這種情況下,可能是末尾(.*?)之后的前瞻性斷言:

(?=<h1|</body>|\z)#ims

忽略有關正則表達式不合適的評論,因為它仍然是一個有趣的問題,有兩種方法可以解決此問題:貪婪和懶惰。

模式的各個部分是:

  • 惰性.*?(?=<h1|\\z)
  • 貪婪(?:[^<]+|<(?!h1))*

通常 ,您可能對貪婪和懶惰的限定詞的表現很熟悉,但是這里的症結要簡單得多。

如果您要匹配的字符串完全由字符< ,則懶惰模式和貪婪模式的性能大致相同,因為它們都必須檢查每個匹配字符的斷言。

但是,在HTML中,其他字符比<字符多得多,因此不必檢查其他字符的貪婪模式可以快幾個數量級。

我承認懶惰模式更易於閱讀,但是我認為非常好的性能是值得的,並且強烈建議無論如何都要使用x修飾符注釋模式。

暫無
暫無

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

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