2010-01-05 215 views
2

Pre scriptum:我完全好奇,並且意識到其他完美合適的解決方案,它位於正則表達式域之外。匹配嵌套標籤

如何從開始標記匹配,直到結束標記可能嵌套,也許相同的標記。所以說,我在HTML文件中已經給:

<div class="nice"> 
    <a href="http://www.google.com">Hello</a> 
    <div>World</div> 
</div> 

比方說我要評論了這一點通過正則表達式替換。人們可以做一個簡單的

/(<div\sclass=\"nice\">(.*)</div>)/ 

但是,當然比賽的那會,直到最後結束的div標籤,渲染代碼犯規,如果漂亮的DIV嵌入另一個DIV中。使分隔符非貪婪會使代碼犯規更多,匹配直到VERY FIRST結束div標記。

那麼有什麼想法?我經常想到這一點,我從來沒有找到解決方案,這在正則表達式中是不可能的,還是隻是我忘記了一些簡單的東西?是不是有某種「回顧」機制?

+0

你會使用哪種語言?如果您逐行讀取數據並將數據存儲在某個數據結構中,那肯定是可行的。 – 2010-01-05 21:51:09

回答

1

通常的建議是不使用正則表達式的HTML,因爲HTML 不是定期。所以試圖用正則表達式來解析它(特別是做一些像上面那樣嚴格的東西)會遇到困難。

+4

HTML不規則的事實並不一定意味着它不能用現代實現的正則表達式進行分析,正則表達式已經超越瞭解析常規語言所需的能力,例如,逆向引用。 – oleks 2010-01-05 22:09:18

2

.NET的正則表達式的實現是可以處理這種情況屈指可數。它提供了一個balanced matching功能,可以使用組並計數來解析嵌套模式。

但是,這仍然不是一個完美的解決方案。例如,如果您將混亂的html註釋放入混合中,那麼即使是平衡匹配的聰明正則表達式也可能會失敗。所以最好使用一個html解析器。

3

平衡匹配似乎是非常正確的工具,大概可以在很多語言中實現,但Perl和.NET盡我所能地做出了最好的嘗試。由於Perl有最簡單的例子,這裏有一個(從http://www.perl.com/pub/a/2003/06/06/regexps.html借用):

$paren = qr/ 
     \(
     ( 
      [^()]+ # Not parens 
     | 
      (??{ $paren }) # Another balanced group (not interpolated yet) 
     )* 
     \) 
    /x; 

的(?? {$括號})僅僅指的是正則表達式本身造成了遞歸正則表達式。美麗的,我想我應該提到,我對這樣的解決方案是開放的,但當然,這根本不是一個純粹的正則表達式的例子,這當然是不可能的定義:)

0

正如其他人所說,這通常是一個壞主意。但你說你只是出於好奇,所以在這裏...

你的問題是不可能解決傳統的正則表達式的概念,但一些引擎,如.NET的,欺騙一點,給你一個方法用「平衡組定義」來做到這一點。

這裏有一個教程:http://www.codeproject.com/KB/recipes/Nested_RegEx_explained.aspx

1

不,我建議使用它,但:

'#\<([\w]+)([^>]*?)(([\s]*\/>)|(\>((([^\<]*?|<\!\-\-.*?\-\->)|(?R))*)\<\/\1[\s]*\>))#sm' 

應該工作,任何標記匹配,可以進行調整,以匹配特定的標籤。