使用正規表示式匹配巢狀Html標籤

2021-07-07 10:01:19 字數 2609 閱讀 8774

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

任何複雜的正規表示式都是由簡單的子表示式組成的,要想寫出複雜的正則來,一方面需要有化繁為簡的功底,另外一方面,我們需要從正則引擎的角度去思考問題。關於正則引擎的原理,推薦《mastering regular expression》中文名叫《精通正規表示式》。挺不錯的一本書。

ok,先確定我們要解決的問題——從一段html文字中找出特定id的標籤的innerhtml

這裡面最大的難點就是,html標籤是支援巢狀的,怎麼能夠找到指定標籤相對應的閉合標籤呢?

我們可以這樣想,先匹配最前面的起始標籤,假設是div吧(

我之所以能夠這樣去思考,是因為我了解過正則的特性,我知道正則中的平衡組能夠實現我剛才說的「堆疊」操作。所以,如果我們要編寫複雜正規表示式,需要對正則的一些高階特性至少有所了解,這樣我們思考問題才有個方向。

這裡假設我們要匹配的文字是一段合法的html文字。下面這段html**是從我的部落格上拷貝下來的,作為我們的測試文字。我們要匹配的就是footer這個div的innerhtml,同時把標籤名也捕獲下來。

<

divstyle

="background-color:gray;"

id="footer"

>

="gotop"

href

="#"

onclick

="mgjs.gotop();return false;"

>top

a>

="powered"

href

="">wordpress

a>

<

divid

>

div>

<

divid

="themeinfo"

>

theme by <

ahref

="">mg12

a>. valid <

ahref

="">xhtml 1.1

a>

and <

ahref

="">css 3

a>.

div>

div>

這裡我們需要借助expresso工具來構建和測試編寫的正規表示式。

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

<(?[\w]+)[^>]*\s[ii][dd]=(?["']?)footer(?(quote)\k)["']?[^>]*>
上面的正規表示式需要做幾點說明:

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

2. (?regex)格式定義乙個命名分組,我們在上面定義了乙個htmltag的標籤分組,用來存放匹配到的html標籤名。quote分組是用來給後面的匹配使用的。

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

((?<\k[^>]*>)|>(?<-nested>)|.*?)*>
在成功匹配到起始標籤之後,後面的html文字可以分為三種情況:

a. 匹配到巢狀div起始標籤b. 匹配到巢狀div起始標籤的閉合標籤,這個時候,需要將之前的nested分組釋放

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

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

update:前面過於側重分析了,最後沒有給出乙個完整的正則真是抱歉。

<(?[\w]+)[^>]*\s[ii][dd]=(?["']?)footer(?(quote)\k)["']?[^>]*>((?<\k[^>]*>)|>(?<-nested>)|.*?)*>
上面這個正則能夠匹配任意id=footer的html標籤。

需要注意,此正規表示式需要設定singleline=true,這樣點號才可以把換行符也匹配進去。

對於domoxz 的問題,如果要匹配p標籤,那麼只需將上述的正則中的<(?[\w]+)替換成<(?p)即可。

使用正規表示式匹配巢狀Html標籤

概述 正規表示式是做文字解析工作必不可少的技能。如web伺服器日誌分析,網頁前端開發等。很多高階文字編輯器都支援正規表示式的乙個子集,熟練掌握正規表示式,經常能夠使你的一些工作事半功倍。例如統計 行數,只需乙個正則就搞定。巢狀html標籤的匹配是正規表示式應用中乙個比較難的話題,因為它涉及到的正則語...

使用正規表示式匹配巢狀Html標籤

正規表示式是做文字解析工作必不可少的技能。如web伺服器日誌分析,網頁前端開發等。很多高階文字編輯器都支援正規表示式的乙個子集,熟練掌握正規表示式,經常能夠使你的一些工作事半功倍。例如統計 行數,只需乙個正則就搞定。巢狀html標籤的匹配是正規表示式應用中乙個比較難的話題,因為它涉及到的正則語法比較...

如何匹配巢狀Html標籤 正規表示式

概述 正規表示式是做文字解析工作必不可少的技能。如web伺服器日誌分析,網頁前端開發等。很多高階文字編輯器都支援正規表示式的乙個子集,熟練掌握正規表示式,經常能夠使你的一些工作事半功倍。例如統計 行數,只需乙個正則就搞定。巢狀html標籤的匹配是正規表示式應用中乙個比較難的話題,因為它涉及到的正則語...