Различия между .NET Capture, Group, Match - PullRequest
6 голосов
/ 12 февраля 2010

Я делаю небольшое приложение, используя типы .NET Regex. И типы «Захват, группировка и сопоставление» меня полностью смутили. Я никогда не видел такого ужасного решения. Может ли кто-нибудь объяснить их использование для меня? Большое спасибо.

Ответы [ 2 ]

12 голосов
/ 12 февраля 2010

Вот более простой пример, чем приведенный в документе @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);
}

результат:

full match: foo%123%456%789
group #1: foo
group #2: 789
group #2 captures: 123, 456, 789

Результаты full match и group #1 просты, но другие требуют некоторого объяснения. Группа № 2, как вы можете видеть, находится внутри группы без захвата, которая контролируется квантификатором +. Он совпадает три раза, но если вы запросите его Value, вы получите только то, что соответствовало ему в третий раз - окончательный захват. Аналогично, если вы используете заполнитель $2 в строке замены, окончательный захват - это то, что вставляется на его место.

В большинстве ароматов регулярных выражений это все, что вы можете получить; каждый промежуточный захват перезаписывается следующим и теряется; .NET практически уникален тем, что сохраняет все снимки и делает их доступными после завершения матча. Вы можете получить к ним прямой доступ, как я сделал здесь, или пройти по CaptureCollection, как если бы вы MatchCollection. Тем не менее, нет эквивалента для заполнителей строки замены $1 в стиле.

Таким образом, причина, по которой дизайн API так уродлив (как вы сказали), двояка: сначала он был адаптирован из встроенной поддержки регулярных выражений в Perl к объектно-ориентированной среде .NET; затем на него была привита структура CaptureCollection. Perl 6 предлагает намного более чистое решение, но авторы достигли этого, переписав Perl практически с нуля и выбросив обратную совместимость из окна.

2 голосов
/ 12 февраля 2010

Совпадение является результатом любого отдельного совпадения полноты регулярного выражения. Обе группы и записи имеют отношение к группам захвата (каждая (expression) внутри регулярного выражения), но различаются по поведению. Вот цитата из статьи MSDN о классе Capture, которая объясняет разницу:

Если вы не применяете квантификатор к группа захвата, группа. Захватывает свойство возвращает CaptureCollection с одним объектом Capture, который предоставляет информацию о том же захватить как объект группы. Если вы делаете применить квантификатор для захвата группа, Group.Index, Group.Length, и свойства Group.Value предоставляют информация только о последнем захваченная группа, тогда как Захват объекты в CaptureCollection предоставить информацию обо всех подвыражение захватывает. Пример предоставляет иллюстрацию.

( Источник )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...