亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Regex > 正文

正則表達式——詳細講解平衡組

2020-03-16 20:54:30
字體:
來源:轉載
供稿:網友

這篇文章適合你嗎?

要讀懂這篇文章的精髓,你最好要有一點正則匹配原理的基礎。比如".*?"匹配文本內容"asp163",稍懂正則表達式的人都知道可以匹配,但是你知道他的匹配過程嗎?如果你不太清楚,那么下面的內容,對你來說可能不太適合,或許,看的太吃力且無法領悟平衡組的用法。因此,我建議你先了解正則表達式NFA引擎的匹配原理。想要整理一份易懂易描述的話,的確要費些時間,但不知道這篇內容會不會達到我預期的效果。慢慢完善吧~(注:這是我2010年寫的,現在拿過來,有時間將自己做為讀者來看本篇文章,修改有問題的地方,并增加些實例,盡量做到通俗易懂。)

一般正則教程中對平衡組的介紹

如果想要匹配可嵌套的層次性結構的話,就得使用平衡組了。舉個例子吧,如何把“xx <aa <bbb> <bbb> aa> yy”這樣的字符串里,最長的尖括號內的內容捕獲出來?

這里需要用到以下的語法構造:
(?<group>) 把捕獲的內容命名為group,并壓入堆棧
(?<-group>) 從堆棧上彈出最后壓入堆棧的名為group的捕獲內容,如果堆棧本來為空,則本分組的匹配失敗
(?(group)yes|no) 如果堆棧上存在以名為group的捕獲內容的話,繼續匹配yes部分的表達式,否則繼續匹配no部分
(?!) 順序否定環視,由于沒有后綴表達式,試圖匹配總是失敗

如果你不是一個程序員(或者你是一個對堆棧的概念不熟的程序員),你就這樣理解上面的三種語法吧:第一個就是在黑板上寫一個(或再寫一個)"group",第二個就是從黑板上擦掉一個"group",第三個就是看黑板上寫的還有沒有"group",如果有就繼續匹配yes部分,否則就匹配no部分。
我們需要做的是每碰到了左括號,就在黑板上寫一個"group",每碰到一個右括號,就擦掉一個,到了最后就看看黑板上還有沒有-如果有那就證明左括號比右括號多,那匹配就應該失?。榱四芸吹酶宄稽c,我用了(?'group')的語法):

<         #最外層的左括號 [^<>]*     #最外層的左括號后面的不是括號的內容 (  (   (?'Open'<) #碰到了左括號,在黑板上寫一個"Open"   [^<>>]*   #匹配左括號后面的不是括號的內容  )+  (   (?'-Open'>) #碰到了右括號,擦掉一個"Open"   [^<>]*   #匹配右括號后面不是括號的內容  )+ )* (?(Open)(?!))  #在遇到最外層的右括號前面,判斷黑板上還有沒有沒擦掉的"Open";如果有,則匹配失敗>         #最外層的右括號

我為什么寫這篇文章

看了上面的介紹,你明白了嗎?在我未理解正則表達式匹配原理之前,看上面對于平衡組的介紹,似懂非懂,且只能當做模板記住,而不能靈活運用。因此查閱大量有關正則方面的資料,這里尤其感謝lxcnn的技術文檔及《精通正則表達式》這本書,讓我對正則表達式有了更深入、更系統的理解,因此,在它們的基礎之上,我就結合自己的學習經歷做個小結,一來做為學習筆記存檔,另外,如果能解決你的疑惑,也是件讓人高興的事。
我先暫不分析上面的代碼,先講解一下關于平衡組相關的概念及知識。
下面表達式匹配測試工具為:Expresso,本站也提供它的完美破解版下載。

平衡組的概念及作用

平衡組,故名思義,平衡即對稱,主要是結合幾種正則語法規則,提供對配對出現的嵌套結構的匹配。平衡組有狹義與廣義兩種定義,狹義平衡組指(?Expression) 語法,而廣義平衡組并不是固定的語法規則,而是幾種語法規則的綜合運用,我們平時所說的平衡組通常指的是廣義平衡組。本文中如無特殊說明,平衡組這種簡寫指的是廣義平衡組。
平衡組的匹配原理
平衡組的匹配原理可以用堆棧來解釋,先舉個例子,再根據例子進行解釋。

源字符串:a+(b*(c+d))/e+f-(g/(h-i))*j
正則表達式:((?<Open>/()|(?<−Open>)|[^()])*(?(Open)(?!))/)
需求說明:匹配成對出現的()中的內容
輸出:(b*(c+d)) 和 (g/(h-i))
我將上面正則表達式代碼分行寫,并加上注釋,這樣看起來有層次,而且方便

 /(        #普通字符“(”  (       #分組構造,用來限定量詞“*”修飾范圍   (?<Open>/() #命名捕獲組,遇到開括弧“Open”計數加1   |      #分支結構   (?<-Open>/)) #狹義平衡組,遇到閉括弧“Open”計數減1   |      #分支結構   [^()]+    #非括弧的其它任意字符  )*       #以上子串出現0次或任意多次  (?(Open)(?!)) #判斷是否還有“Open”,有則說明不配對,什么都不匹配 /)       #普通閉括弧

對于一個嵌套結構而言,開始和結束標記都是確定的,對于本例開始為“(”,結束為“)”,那么接下來就是考察中間的結構,中間的字符可以劃分為三類,一類是“(”,一類是“)”,其余的就是除這兩個字符以外的任意字符。

那么平衡組的匹配原理就是這樣的

1、先找到第一個“(”,作為匹配的開始。即上面的第1行,匹配了:a+(b*(c+d))/e+f-(g/(h-i))*j (紅色顯示部分)

2、在第1步以后,每匹配到一個“(”,就入棧一個Open捕獲組,計數加1

3、在第1步以后,每匹配到一個“)”,就出棧最近入棧的Open捕獲組,計數減1

也就是講,上面的第一行正則“/(”匹配了:a+(b*(c+d))/e+f-(g/(h-i))*j (紅色顯示部分)
然后,匹配到c前面的“(”,此時,計數加1;繼續匹配,匹配到d后面的“)”,計算減1;——注意嘍:此時堆棧中的計數是0,正則還是會向前繼續匹配的,但是,如果匹配到“)”的話,比如,這個例子中d))(紅色顯示的括號)——引擎此時將控制權交給(?(Open)(?!)),判斷堆棧中是否為0,如果為0,則執行匹配“no”分支,由于這個條件判斷結構中沒有“no”分支,所以什么都不做,把控制權交給接下來的“/)”
這個正則表達式“/)”可匹配接下來的),即b))(紅色顯示的括號)

4、后面的 (?(Open)(?!))用來保證堆棧中Open捕獲組計數是否為0,也就是“(”和“)”是配對出現的

5、最后的“)”,作為匹配的結束

匹配過程

首先匹配第一個“(”,然后一直匹配,直到出現以下兩種情況之一時,把控制權交給(?(Open)(?!)):
a)堆棧中Open計數已為0,此時再遇到“)”
b)匹配到字符串結束符
這時控制權交給(?(Open)(?!)),判斷Open是否有匹配,由于此時計數為0,沒有匹配,那么就匹配“no”分支,由于這個條件判斷結構中沒有“no”分支,所以什么都不做,把控制權交給接下來的“/)”
如果上面遇到的是情況a),那么此時“/)”可以匹配接下來的“)”,匹配成功;
如果上面遇到的是情況b),那么此時會進行回溯,直到“/)”匹配成功為止,否則報告整個表達式匹配失敗。
由于.NET中的狹義平衡組“(?<Close-Open>Expression)”結構,可以動態的對堆棧中捕獲組進行計數,匹配到一個開始標記,入棧,計數加1,匹配到一個結束標記,出棧,計數減1,最后再判斷堆棧中是否還有Open,有則說明開始和結束標記不配對出現,不匹配,進行回溯或報告匹配失?。蝗绻麤]有,則說明開始和結束標記配對出現,繼續進行后面子表達式的匹配。
需要對“(?!)”進行一下說明,它屬于順序否定環視,完整的語法是“(?!Expression)”。由于這里的“Expression”不存在,表示這里不是一個位置,所以試圖嘗試匹配總是失敗的,作用就是在Open不配對出現時,報告匹配失敗。

下面在看個例子:

<table><tr><td id="td1"> </td><td id="td2"><table><tr><td>snhame</td><td>f</td></tr></table></td><td></td></tr> </table>

以上為部分的HTML代碼.現在我們的問題是要提取出其<td id="td2">的<td>標簽并將其刪除掉,以往我們慣用的方法都是直接去取,像<td/s*id="td2">[/s/S]+?/</td>,不過問題出來了,我們提取到的不是我們想要的內容,而是

<td id="td2"><table><tr><td>snhame</td>

原因也很簡單,它和離他最近的</td>標簽匹配上了,不過它不知道這個標簽不是它的-_-,是不是就是?符號的原因呢,我們去掉讓他無限制貪婪,可這下問題更大了,什么亂七八糟的東東它都匹配到了

<td id="td2"><table><tr><td>snhame</td><td>f</td></tr></td><td></td>

這個結果也不是我們想要的。那么我就用“平衡組”來解決吧。

<td/s*id="td2"[^>]*>((?<mm><td[^>]*>)+|(?<-mm></td>)|[/s/S])*?(?(mm)(?!))</td>

匹配的結果是

<td id="td2"><table><tr><td>snhame</td><td>f</td></tr></table></td><td></td>

這正是我們想要的
注意,我開始寫成這樣的方式

<td/s*id="td2"[^>]*>((?<mm><td[^>]*>)+|(?<-mm></td>)|[/s/S])*(?(mm)(?!))</td> 

匹配的結果是

<td id="td2"><table><tr><td>snhame</td><td>f</td></tr></table></td><td></td>

一個問題
以下代碼只是做為一個問題探討
文本內容:e+f(-(g/(h-i))*j

正則表達式:

/( (  (?<mm>/()  |  (?<-mm>/))  |  . )*? (?(mm)(?!))/)

匹配的結果是:(-(g/(h-i))

 

注:相關教程知識閱讀請移步到正則表達式頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品自拍偷拍| 久久综合免费视频| 色老头一区二区三区| 大胆人体色综合| 久久人体大胆视频| www.国产精品一二区| 欧美激情亚洲激情| 欧美极品xxxx| 91精品视频免费看| 亚洲欧美一区二区精品久久久| 久久精品福利视频| 日韩有码片在线观看| 成人h视频在线观看播放| 成人在线免费观看视视频| 亚洲二区中文字幕| 国产ts一区二区| 欧美亚洲一级片| 国产精品∨欧美精品v日韩精品| 俺去了亚洲欧美日韩| 国产成人综合精品在线| 国产成人福利网站| 亚洲欧美日韩直播| 欧美激情在线观看| 精品亚洲永久免费精品| 亚洲色图17p| 国产精品爽黄69天堂a| 久久久久久久久综合| 久久久久久九九九| 国产99久久精品一区二区| 中文字幕日韩在线观看| 久久久国产一区二区| 亚洲嫩模很污视频| 美女啪啪无遮挡免费久久网站| 日韩av网址在线| 亚洲欧洲高清在线| 欧美激情乱人伦一区| 亚洲精品自拍偷拍| 国产成人小视频在线观看| 欧美精品18videos性欧| 国产精品久久久久久久久久久久| 久久夜色精品国产| 国产精品久久久久久久久久东京| 91精品中国老女人| 成人女保姆的销魂服务| 久久久久久噜噜噜久久久精品| 91精品久久久久久久久久久久久久| 日韩在线一区二区三区免费视频| 日韩电影大全免费观看2023年上| 中文字幕国产日韩| 亚洲黄色在线看| 国产精品视频播放| 久久91精品国产91久久跳| 青青草99啪国产免费| 欧美精品情趣视频| 亚洲成人精品av| 亚洲最大av网| 欧美视频免费在线| 亚洲精品中文字幕有码专区| 精品视频在线观看日韩| 午夜精品久久17c| 亚洲视频日韩精品| 97热精品视频官网| 日韩中文字幕在线| 中文字幕欧美专区| 日韩成人在线免费观看| 欧美中文字幕精品| 91av在线视频观看| 38少妇精品导航| 中文字幕日韩精品在线观看| 日韩一区二区久久久| 久久亚洲一区二区三区四区五区高| 成人两性免费视频| 精品国产91乱高清在线观看| 久久久国产在线视频| 亚洲激情视频在线| 久久久久免费视频| 成人黄色大片在线免费观看| 国产欧美一区二区三区视频| 日韩成人中文字幕| 国产99久久精品一区二区永久免费| 日本亚洲欧美成人| 精品福利视频导航| 欧美性xxxx在线播放| 国产精品wwwwww| 亚洲美女在线观看| 欧美一级大片在线观看| 亚洲成人激情在线| 成人午夜激情网| 97精品国产97久久久久久春色| 97涩涩爰在线观看亚洲| 日韩av电影在线播放| 国产精品9999| 久久最新资源网| 中文字幕日韩精品有码视频| 日韩少妇与小伙激情| 日韩欧美大尺度| 久久久之久亚州精品露出| 亚洲va欧美va国产综合剧情| 97视频人免费观看| 国产一区二区三区网站| 91网站在线免费观看| 亚洲网站在线看| 国产精品久久久久久久av大片| 欧美高跟鞋交xxxxxhd| 久久久国产精彩视频美女艺术照福利| 亚洲xxxx视频| 在线视频中文亚洲| 色悠久久久久综合先锋影音下载| 国产91亚洲精品| 国产精品日日摸夜夜添夜夜av| 日韩专区在线播放| 亚洲色图35p| 欧美一级黄色网| 久久国产天堂福利天堂| 日韩视频免费中文字幕| 色妞在线综合亚洲欧美| 啊v视频在线一区二区三区| 欧美大片免费观看在线观看网站推荐| 最新69国产成人精品视频免费| 一区二区三区视频免费在线观看| 欧美亚洲另类制服自拍| 亚洲成人网av| 亚洲欧美色婷婷| 亚洲精品久久久久中文字幕二区| 国产成人综合精品在线| 国产专区欧美专区| 91国产高清在线| 欧美成人免费在线观看| 亚洲日本欧美中文幕| 精品高清一区二区三区| 日韩欧美一区二区三区| 国产自摸综合网| 欧美有码在线观看视频| 亚洲欧美成人在线| 国产精品美女久久久久av超清| 欧美日韩中文在线观看| 91在线精品播放| 性色av一区二区三区红粉影视| 欧美综合激情网| 日韩av中文字幕在线免费观看| 日韩av免费在线观看| 日日骚av一区| 欧美另类极品videosbest最新版本| 欧美怡春院一区二区三区| 精品女厕一区二区三区| 久久精品国产精品| 国产精品电影久久久久电影网| 久久人人爽人人| 亚洲r级在线观看| 九九热视频这里只有精品| 欧美另类老肥妇| 成人免费在线视频网址| 搡老女人一区二区三区视频tv| 精品无码久久久久久国产| 最近2019年中文视频免费在线观看| 国产精品h片在线播放| 精品久久久国产| 亚洲国产一区二区三区四区| 国产精品自产拍在线观看| 国产精品入口尤物| 亚洲久久久久久久久久| 欧美疯狂xxxx大交乱88av| 日本aⅴ大伊香蕉精品视频| 国产精品久久久久久av福利软件|