2017-01-13 114 views
1

我寫這個正則表達式:C#正則表達式匹配的子表達式返回空字符串

var cellPattern = new Regex(@"(?(?=\d+)\d+|\|)\s(.)\s", RegexOptions.Compiled | RegexOptions.Multiline); 

,並從該字符串得到的細胞:

string field = 
" A B C D E \n" + 
"1 | X | | | \n" + 
" ---+---+---+---+---\n" + 
"2 | | | | \n" + 
" ---+---+---+---+---\n" + 
"3 | O | | | \n" + 
" ---+---+---+---+---\n" + 
"4 | | | X | \n" + 
" ---+---+---+---+---\n" + 
"5 | | | | \n" + 
"O >>> "; 

我執行cellPattern.Matches(field);它返回MatchCollection有25場比賽,但爲什麼所有的比賽都有一個空字符串作爲第一組?

PS: 如果我使用了一個名爲匹配的子表達式,一切正常,我想要的方式:所有的比賽都有網格單元爲「細胞」組

var cellPattern = new Regex(@"(?(?=\d+)\d+|\|)\s(?<cell>.)\s", RegexOptions.Compiled | RegexOptions.Multiline); 

PPS:我的項目框架是.NET Framework 4.5.2

PPPS:在this site,你也可以看到此行爲

回答

1

這是.NET框架中的一個錯誤。然後使用(?(?=)),它會忽略下一個組的內容,但它仍然會計入組數。

當它看到(?(它設置一個標誌忽略下一個組,希望看到(?(expression) ... | ...),而是有一個(?= ...),所以標記不會被重置,直到下一次捕獲組。

一個解決將是命名組,添加一個虛擬組:

(?(?=\d+)\d+|\|)()\s(.)\s 

或加括號的另一個層面:

(?((?=\d+))\d+|\|)\s(.)\s 

在這種情況下,你也可以刪除條件:

(?:\d+|\|)()\s(.)\s 
+0

感謝您的解釋!此外,我已經將「正則表達式」簡化爲「@」[\ d |](。)「',但這不是主題 – KgOfHedgehogs

相關問題