當前位置:
首頁 > 知識 > 使用正則表達式匹配嵌套Html標籤

使用正則表達式匹配嵌套Html標籤

正則表達式是做文本解析工作必不可少的技能。如Web伺服器日誌分析,網頁前端開發等。很多高級文本編輯器都支持正則表達式的一個子集,熟練掌握正則表達式,經常能夠使你的一些工作事半功倍。例如統計代碼行數,只需一個正則就搞定。嵌套Html標籤的匹配是正則表達式應用中一個比較難的話題,因為它涉及到的正則語法比較多,也比較難。因此也就更有研究的價值。

先確定我們要解決的問題——從一段Html文本中找出特定id的標籤的innerHTML

我們可以這樣想,先匹配最前面的起始標籤,假設是div吧(<div),然後一旦遇到嵌套div,就「壓入堆棧」,然後一遇到div結束標籤了,就「彈出堆棧」。如果遇到結束標籤的時候,堆棧裡面已經沒有東西了,那麼匹配結束,此結束標籤為正確的閉合標籤。

這裡假設我們要匹配的文本是一段合法的Html文本

<div id="myID">

<div class="s-sub">

<ul>

<li class="s-hw"><a href="http://consumer.huawei.com/cn/" target="_blank">華為官網</a></li>

<li class="s-honor"><a href="http://www.honor.cn/" target="_blank">華為榮耀</a></li>

<li class="s-emui"><a href="http://emui.huawei.com/cn/" target="_blank">EMUI</a></li>

<li class="s-appstore"><a href="http://appstore.huawei.com/" target="_blank">應用市場</a></li>

<li class="s-cloud"><a href="http://cloud.huawei.com/cn" target="_blank">雲服務</a></li>

<li class="s-developer"><a href="http://developer.huawei.com/" target="_blank">開發者聯盟</a></li>

<li class="s-club"><a href="http://club.huawei.com" target="_blank">花粉俱樂部</a></li>

</ul>

</div>

<p>test text</p>

<div>

<p>test text</p>

</div>

</div>

匹配起始標籤

起始標籤特徵很好提取,以尖括弧打頭,然後跟著一連串英文字母,然後一大串屬性中(非尖括弧字元)匹配id(不區分大小寫)=myID。需要注意的是,myID可以被雙引號或者單引號包裹,也可以什麼都不加。正則如下:

<(?<HtmlTag>[w]+)[^>]*s[iI][dD]=(?<Quote>[""]?)myID(?(Quote)k<Quote>)[^>]*?(/>|>

上面的正則表達式需要做幾點說明:

1. <尖括弧在正則中算是一個特殊字元,在顯式捕獲分組中用它將分組名括起來。但是因為開頭的尖括弧在此上下文下並不會出現解析歧義,因此加不加轉義符效果是一樣的。

2. (?<GroupName>RegEx)格式定義一個命名分組,我們在上面定義了一個HtmlTag的標籤分組,用來存放匹配到的Html標籤名。Quote分組是用來給後面的匹配使用的。

3. (?(GroupName)Then|Else)是條件語句,表示當捕獲到GroupName分組時執行Then匹配,否則執行Else匹配。上面的正則中,我們先嘗試匹配footer字元串左邊的引號,並將其存入LeftQuote分組中,然後在footer右側進行條件解析,如果之前匹配到LeftQuote分組,那麼右側也應該批評LeftQuote分組。這樣一來,我們就能精確匹配id的各種情況了。

匹配閉合標籤

((?<Nested><k<HtmlTag>[^>]*>)|</k<HtmlTag>>(?<-Nested>)|.*?)*</k<HtmlTag>>

在成功匹配到起始標籤之後,後面的Html文本可以分為三種情況:

A. 匹配到嵌套div起始標籤<div,這個時候,需要將其捕獲到Nested分組。

B. 匹配到嵌套div起始標籤的閉合標籤,這個時候,需要將之前的Nested分組釋放

C. 其他任意文本。注意,需要使用.*?方式關閉貪婪匹配,否則最後的閉合標籤可能會過度匹配

使用(RegEx1|RegEx2|RegEx3)*這種方式,可以將幾個條件以或的形式組合起來,然後再取若干次匹配結果,最終再匹配閉合標籤。其中(?<-Nested>)是表示釋放之前捕獲的Nested分組。確切的語法是(?<N-M>)即使用N分組替換掉M分組,如果N分組沒有指定或不存在,則釋放M分組。

完整的正則表達式為:

<(?<HtmlTag>[w]+)[^>]*s[iI][dD]=(?<Quote>[""]?)myID(?(Quote)k<Quote>)[^>]*?(/>|>((?<Nested><k<HtmlTag>[^>]*>)|</k<HtmlTag>>(?<-Nested>)|.*?)*</k<HtmlTag>>)

使用正則表達式匹配嵌套Html標籤

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

netty整合springMVC,實現高效的HTTP服務請求
餓了么大數據計算引擎實踐與應用

TAG:程序員小新人學習 |