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