2017-01-13 5 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 framework. Затем, используя (?(?=)), он игнорирует содержимое следующей группы, но по-прежнему учитывает количество групп.

Когда он видит (?( он устанавливает флаг игнорировать следующую группу, ожидая увидеть (?(expression) ... | ...), но вместо этого есть (?= ...), так что флаг не не сбрасывается до следующей группы захвата.

исправление было бы назвать группу, добавить фиктивную группу:

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

или добавить еще один уровень скобок:

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

В этом случае, вы можете также удалить условное:

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

Спасибо за разъяснение! Также я уже упростил регулярное выражение '@" [\ d |] (.) "', Но это не в тему – KgOfHedgehogs