匹配平衡組 , 匹配括號組

2021-06-17 19:39:09 字數 1400 閱讀 7027

這裡介紹的平衡組語法是由.net framework支援的;其它語言/庫不一定支援這種功能,或者支援此功能但需要使用不同的語法。

有時我們需要匹配像( 100 * ( 50 + 15 ) )這樣的可巢狀的層次性結構,這時簡單地使用\(.+\)則只會匹配到最左邊的左括號和最右邊的右括號之間的內容(這裡我們討論的是貪婪模式,懶惰模式也有下面的問題)。假如原來的字串裡的左括號和右括號出現的次數不相等,比如( 5 / ( 3 + 2 ) ) ),那我們的匹配結果裡兩者的個數也不會相等。有沒有辦法在這樣的字串裡匹配到最長的,配對的括號之間的內容呢?

為了避免(和\(把你的大腦徹底搞糊塗,我們還是用尖括號代替圓括號吧。現在我們的問題變成了如何把xx aa> yy這樣的字串裡,最長的配對的尖括號內的內容捕獲出來?

這裡需要用到以下的語法構造:

如果你不是乙個程式設計師(或者你自稱程式設計師但是不知道堆疊是什麼東西),你就這樣理解上面的三種語法吧:第乙個就 是在黑板上寫乙個"group",第二個就是從黑板上擦掉乙個"group",第三個就是看黑板上寫的還有沒有"group",如果有就繼續匹配yes部 分,否則就匹配no部分。

我們需要做的是每碰到了左括號,就在壓入乙個"open",每碰到乙個右括號,就彈出乙個,到了最後就看看堆疊是否為空--如果不為空那就證明左括號比右括號多,那匹配就應該失敗。正規表示式引擎會進行回溯(放棄最前面或最後面的一些字元),盡量使整個表示式得到匹配。

<

#最外層的左括號

[^<>]*

#最外層的左括號後面的不是括號的內容((

(?'open

'<

)    #碰到了左括號,在黑板上寫乙個

"open"[

^<>]*

#匹配左括號後面的不是括號的內容)+

((?'

-open

'>

)   #碰到了右括號,擦掉乙個

"open"[

^<>]*

#匹配右括號後面不是括號的內容)+

)*(?

(open)(

?!))         #在遇到最外層的右括號前面,判斷黑板上還有沒有沒擦掉的

"open

";如果還有,則匹配失敗

>

#最外層的右括號

平衡組的乙個最常見的應用就是匹配html,下面這個例子可以匹配巢狀的標籤:

<

div[

^>

]*>

[^<>]*

(((?

'open

'<

div[

^>

]*>

)[^<>]*

)+((?

'-open

'div

>

)[^<>]*

)+)*

(?(open)(

?!))

div>

匹配平衡組

reference 匹配一般是指左側符號與右側符號兩兩出現,例如 與 與 或者 但是左右符號可能有內嵌,正規表示式通過寫入堆疊,推出堆疊來正確匹配左右符號 例如 a b c d e f g h i j匹配第乙個左右符號 我們先匹配左側 隨後對中間字串逐一讀取 乙個中間字元他有3種情況,再次出現乙個 ...

平衡組 遞迴匹配

有時我們需要匹配像 100 50 15 這樣的可巢狀的層次性結構,這時簡單地使用 則只會匹配到最左邊的左括號和最右邊的右括號之間的內容 這裡我們討論的是貪婪模式,懶惰模式也有下面的問題 假如原來的字串裡的左括號和右括號出現的次數不相等,比如 5 3 2 那我們的匹配結果裡兩者的個數也不會相等。有沒有...

捕獲組匹配

re.sub在替換替換字串中可以使用組號,在替換內容中以 n 形式出現的轉移序列都會被模式中與組n匹配的字元替換掉。對於模式 000 2017 11 06 組0 000 2017 11 06 組1 2017 組2 11 組3 06 example d d d ex re.compile exampl...