.net c# Regex 平衡組/遞迴匹配

來源:互聯網
上載者:User
平衡組/遞迴匹配

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

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

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

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

  • (?'group') 把捕獲的內容命名為group,並壓入堆棧(Stack)
  • (?'-group') 從堆棧上彈出最後壓入堆棧的名為group的捕獲內容,如果堆棧本來為空白,則本分組的匹配失敗
  • (?(group)yes|no) 如果堆棧上存在以名為group的捕獲內容的話,繼續匹配yes部分的運算式,否則繼續匹配no部分
  • (?!) 零寬負向先行斷言,由於沒有尾碼運算式,試圖匹配總是失敗

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

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

 

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

>                         #最外層的右括弧

 

平衡組的一個最常見的應用就是匹配HTML,下面這個例子可以匹配嵌套的<div>標籤:

 

<div[^>]*>[^<>]*(((?'Open'<div[^>]*>)[^<>]*)+((?'-Open'</div>)[^<>]*)+)*(?(Open)(?!))</div>

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.