2015-05-04 3 views
5

Допустим, у меня есть следующее регулярное выражение:Получить имени группы подшаблоном из объекта .NET регулярное выражение

var r = new Regex("Space(?<entry>[0-9]{1,3})"); 

Тогда у меня есть строка:

"Space123" 

Вот моя программа:

void Main() 
{ 
    Regex r = new Regex("Space(?<entry>[0-9]{1,3})", RegexOptions.ExplicitCapture); 
    foreach (Match m in r.Matches("Space123")){ 
     m.Groups["entry"].Dump(); //Dump() is linqpad to echo the object to console 
    } 
} 

Что я хочу знать, есть ли способ получить часть регулярного выражения, которая соответствует? В этом случае:

(?<entry>[0-9]{1,3}) 

Я не могу найти его нигде в объекте, но можно было бы подумать, что он будет доступен.

+0

Я не уверен в вашем вопросе ... выражение регулярного выражения, которое соответствует шаблону, который вы использовали 'Space (? [0-9] {1,3}) '. Это то, что вам нужно? –

+0

Правильно, но я хочу получить его из объекта, только часть захвата, а именно ( [0-9] {1,3}), а не всю строку. – Matt

+0

Насколько я знаю, регулярные выражения обычно реализуются путем создания конечной машины за кулисами, которая анализирует синтаксис и выплевывает логический результат. Поэтому одно регулярное выражение - это, в основном, его собственная автономная система. Единственный способ, которым я могу сделать то, что вы хотите, - сделать несколько меньших регулярных выражений и сопоставить их со своим текстом отдельно. – cmcquillan

ответ

5

Вы можете использовать метод Regex.ToString(), который хранит шаблон регулярного выражения. Именованные группы захвата и их соответствующие индексы могут быть получены с использованием Regex.GetGroupNames() и Regex.GetGroupNumbers().

Кроме того, нам нужен массив/список групп захвата внутри шаблона регулярных выражений, поэтому я добавляю regex rxPairedRoundBrackets, чтобы захватить все тексты в круглых скобках без рамки.

Я предлагаю этот код, чтобы получить регулярное выражение подшаблона для конкретного имени группы (редактировать: теперь, даже обработку вложенных неэкранированных вводных групп!):

var rxPairedRoundBrackets = new Regex(@"(?sx)(?=((?<=[^\\]|^)\(
     (?> 
      (?! (?<!\\)\(| (?<!\\)\)) . 
      | 
      (?<!\\)\((?<Depth>) 
      | 
      (?<!\\)\) (?<-Depth>) 
     )* 
     (?(Depth)(?!)) 
     (?<!\\)\)))+"); 
var r = new Regex(@"(?<OuterSpace>Spa(?<ce>ce))(?<entry>\([0-9]{1,3}\))", RegexOptions.ExplicitCapture); 
var bracketedGrps = rxPairedRoundBrackets.Matches(r.ToString()).Cast<Match>().Select(p => p.Groups[1].Value); 
var GroupDict = r.GetGroupNames().Zip(r.GetGroupNumbers(), (s, i) => new { s, i }) 
           .ToDictionary(item => item.s, item => item.i); 
foreach (Match m in r.Matches("My New Space(123)")) 
{ 
    var id = "entry"; 
    var grp = m.Groups[id]; // Just to see the group value 
    var groupThatMatched = bracketedGrps.ElementAt(GroupDict[id] - 1); 
} 

А вот код для ваших случай:

r = new Regex("Space(?<entry>[0-9]{1,3})", RegexOptions.ExplicitCapture); 
bracketedGrps = rxPairedRoundBrackets.Matches(r.ToString()).Cast<Match>().Select(p => p.Groups[1].Value); 
GroupDict = r.GetGroupNames().Zip(r.GetGroupNumbers(), (s, i) => new { s, i }) 
          .ToDictionary(item => item.s, item => item.i); 
foreach (Match m in r.Matches("Space123")) 
{ 
    var id = "entry"; 
    var grp = m.Groups[id]; 
    var groupThatMatched = bracketedGrps.ElementAt(GroupDict[id] - 1); 
} 

Выход:

enter image description here

Смежные вопросы