程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#正則表達式的遞歸婚配剖析

C#正則表達式的遞歸婚配剖析

編輯:C#入門知識

C#正則表達式的遞歸婚配剖析。本站提示廣大學習愛好者:(C#正則表達式的遞歸婚配剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是C#正則表達式的遞歸婚配剖析正文


在C#法式設計中常常會碰到如許的需求,請求婚配出成對的小括號裡的內容,然則普通正則表達式中的 ?R 的語法仿佛在C#中不被支撐, 經由一番查找與測試,終究找到以下一段描寫

/(  應當是 \( 不是用 /本義而是用 \來本義

婚配嵌套的結構

微軟公司曾經包括了一個風趣的立異來婚配穩固的結構(汗青上,這是正則表達式所做不到的)。這其實不輕易控制 — 雖然這節較短,然則留意,它異常的艱澀難明。
從一個例子開端能夠更簡略一些,所以我用這段代碼作為開端:

Regex r = new Regex(@"/((?>[^()]+|/((?<DEPTH>)|/)(?<-DEPTH>))*(?(DEPTH)(?!))/)"); 

這能婚配到首個完整配對的括號組,好比"before (nope (yes (here) okay) after"外面的"(yes (here) okay)"。留意第一個左括號沒有被婚配到,由於沒有和它婚配的右括號。

上面是它若何運作的概覽:

1、在每一個"("被婚配到的時刻,"(?<DEPTH>)"在這裡加上一,告知正則表達式體系以後括號嵌套的深度( 正則表達式開首的"/("不包含在這裡)。

2、在每一個")"被婚配到的時刻,"(?<-DEPTH>)"從深度值內減一。

3、"(?(DEPTH)(?!))"包管在婚配最初一個右括號之前深度為零。

它能任務的緣由在於引擎的回逆客棧保留了婚配勝利的組的軌跡。"(?<DEPTH>)"不外是一個帶著名稱的分組結構,它將老是婚配勝利(不婚配任何器械)。而因為它被緊接著放在"/("以後,它的勝利婚配(依然在客棧上直到被移除)被用於左括號的計數。

譯注:還有一種寫法是"(?<DEPTH>/()",我小我比擬愛好這類情勢,而不是"/((?<DEPTH>)"。前面的"/)(?<-DEPTH>)"也是一樣。

如許,婚配勝利了的名為"DEPTH"的分組的計數在回逆客棧上被樹立起來。而當找到右括號的時刻我們還願望從深度值減一,這是由.NET特殊的語法結構"(?<-DEPTH>)"完成的,它將從客棧上移除比來婚配的"DEPTH"分組。假如客棧上曾經沒有記載,"(?<-DEPTH>)"分組婚配掉敗,從而避免了正則表達式體系婚配過剩的右括號。

最初,"(?(DEPTH)(?!))"是一個用於"(?!)"的斷言,假如"DEPTH"分組到今朝為止照樣勝利的話。假如當我們婚配到這裡時照樣勝利的,這裡有個未配對的左括號還沒有被"(?<-DEPTH>)"移除。在這類情形,我們願望停滯婚配(我們不願望婚配一個未配對的括號),所以我們應用"(?!)",它是一個“零寬度負猜測先行斷言”,僅當子表達式不在此地位的右邊婚配時才持續婚配。
這就是在.NET的正則表達式完成中婚配嵌套構造的辦法。

以上內容仿佛很難明, 其實假如覺的難明的話也簡略,那你就不要去懂得,你只需能用就OK了,把() 調換成你要的字符,信任可以處理很多你的成績,

以下依據這個用法寫了個測試用例

private void button3_Click( object sender, EventArgs e )
{
    Regex r = new Regex( @"/[(?>[^/[/]]+|/[(?<DEPTH>)|/](?<-DEPTH>))*(?(DEPTH)(?!))/]" );
    StringBuilder sb = new StringBuilder();
    MatchString( "[111[222[333]]][222[333]][333]", r, sb );
    MessageBox.Show( sb.ToString(), "取到的信息" );
}
private void MatchString( string OutString, Regex r, StringBuilder sb )
{
    MatchCollection ms = r.Matches( OutString );// 獲得一切的婚配
    foreach ( Match m in ms )
    {
          if ( m.Success )
          {
               sb.AppendLine( m.Groups[0].Value );
               MatchString( m.Groups[0].Value.Substring( 1, m.Groups[0].Value.Length - 1 ), r, sb );// 去失落婚配到的頭和尾的 "[" 和 "]",防止墮入逝世輪回遞歸中,招致溢出
           }
     }
     return;
}

可以獲得

[111[222[333]]] [222[333]] [333] [222[333]] [333] [333] 

信任本文所述對年夜家的C#法式設計有必定的自創價值。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved