Я делаю маленький applicaiton использованием.NET типы Regex. И "Получение, Группа и Соответствие" типы полностью смутили меня. Я никогда не видел такого ужасного решения. Кто-то мог объяснить их использование для меня?Большое спасибо.
Вот более простой пример, чем тот, что указан в документе @Dav:
string s0 = @"foo%123%456%789";
Regex r0 = new Regex(@"^([a-z]+)(?:%([0-9]+))+$");
Match m0 = r0.Match(s0);
if (m0.Success)
{
Console.WriteLine(@"full match: {0}", m0.Value);
Console.WriteLine(@"group #1: {0}", m0.Groups[1].Value);
Console.WriteLine(@"group #2: {0}", m0.Groups[2].Value);
Console.WriteLine(@"group #2 captures: {0}, {1}, {2}",
m0.Groups[2].Captures[0].Value,
m0.Groups[2].Captures[1].Value,
m0.Groups[2].Captures[2].Value);
}
результат:
полное совпадение: foo% 123% 456% 789
группа № 1: foo
группа № 2: 789
группа № 2 захватывает : 123, 456, 789
Результаты полного соответствия
и группа №1
очевидны, но остальные требуют некоторых пояснений. Группа №2, как вы можете видеть, находится внутри группы без захвата, которая контролируется квантификатором +
. Он совпадает три раза, но если вы запросите его Значение
, вы получите только то, что совпадало в третий раз - окончательный захват. Точно так же, если вы используете заполнитель $ 2
в строке замены, окончательный захват будет вставлен вместо него.
В большинстве разновидностей регулярных выражений это все, что вы можете получить; каждый промежуточный захват перезаписывается следующим и теряется; .NET почти уникален в том, что сохраняет все захваченные данные и делает их доступными после выполнения сопоставления.Вы можете получить к ним доступ напрямую, как я сделал здесь, или пройти через CaptureCollection
, как если бы вы использовали MatchCollection
. Однако нет эквивалента для заполнителей замещающей строки в стиле $ 1
.
Таким образом, дизайн API такой уродливый (как вы выразились) по двум причинам: сначала он был адаптирован из встроенной поддержки регулярных выражений Perl в объектно-ориентированную структуру .NET; затем на него была прививалась структура CaptureCollection
. Perl 6 предлагает гораздо более чистое решение, но авторы добились этого, переписав Perl практически с нуля и исключив обратную совместимость.
Совпадение - это результат любого отдельного совпадения целого регекса. Groups и Captures оба имеют отношение к группам захвата (каждое (выражение)
из regex), но различаются тем, как они себя ведут. Вот цитата из статьи MSDN о классе Capture, которая объясняет разницу:
Если не применять квантификатор к группе захвата, свойство Group.Captures возвращает коллекцию CaptureCollection с одним объектом Capture, который предоставляет информацию о том же захвате, что и объект Group. Если вы применить квантификатор к захвату группе, свойства Group.Index, Group.Length, и Group.Value предоставляют информацию только о последней захваченной группе, в то время как объекты Capture объекты в коллекции CaptureCollection предоставляют информацию обо всех захватах подвыражений. Пример содержит иллюстрацию.
(Source)