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#法式設計有必定的自創價值。