Группы регулярных выражений в C # - PullRequest
40 голосов
/ 16 июня 2011

Я унаследовал блок кода, который содержит следующее регулярное выражение, и я пытаюсь понять, как он получает свои результаты.

var pattern = @"\[(.*?)\]";
var matches = Regex.Matches(user, pattern);
if (matches.Count > 0 && matches[0].Groups.Count > 1)
    ...

Для ввода user == "Josh Smith [jsmith]":

matches.Count == 1
matches[0].Value == "[jsmith]"

... что я понимаю. Но тогда:

matches[0].Groups.Count == 2
matches[0].Groups[0].Value == "[jsmith]"
matches[0].Groups[1].Value == "jsmith" <=== how?

Глядя на этот вопрос из того, что я понимаю, в коллекции Groups хранится как полное совпадение, так и предыдущее совпадение. Но разве приведенное выше регулярное выражение не подходит только для [открытой квадратной скобки] [текста] [закрытой квадратной скобки], так почему же «jsmith» соответствует?

Кроме того, всегда ли коллекция групп будет хранить ровно 2 группы: полное совпадение и последнее совпадение?

Ответы [ 5 ]

95 голосов
/ 16 июня 2011
  • match.Groups[0] всегда совпадает с match.Value, что является полным совпадением.
  • match.Groups[1] - первая группа захвата в вашем регулярном выражении.

Рассмотрим этот пример:

var pattern = @"\[(.*?)\](.*)";
var match = Regex.Match("ignored [john] John Johnson", pattern);

В этом случае

  • match.Value равно "[john] John Johnson"
  • match.Groups[0] всегда совпадает с match.Value, "[john] John Johnson".
  • match.Groups[1] - группа захватов из (.*?).
  • match.Groups[2] - группа захватов из (.*).
  • match.Groups[1].Captures - это еще одно измерение.

Рассмотрим другой пример:

var pattern = @"(\[.*?\])+";
var match = Regex.Match("[john][johnny]", pattern);

Обратите внимание, что мы ищем одно или несколько имен в скобках в строке.Вы должны быть в состоянии получить каждое имя отдельно.Введите Captures!

  • match.Groups[0] всегда совпадает с match.Value, "[john][johnny]".
  • match.Groups[1] - группа захватов из (\[.*?\])+.То же, что и match.Value в этом случае.
  • match.Groups[1].Captures[0] совпадает с match.Groups[1].Value
  • match.Groups[1].Captures[1] равно [john]
  • match.Groups[1].Captures[2] равно [johnny]
24 голосов
/ 16 июня 2011

( ) действует как группа захвата.Таким образом, в массиве совпадений есть все совпадения, которые C # находит в вашей строке, а в подмассиве содержатся значения групп захвата внутри этих совпадений.Если вам не нужен этот дополнительный уровень захвата, удалите ( ).

2 голосов
/ 16 июня 2011

Как? Ответ здесь

(.*?)

Это подгруппа из @ "[(. *?)];

2 голосов
/ 16 июня 2011

В скобках также указывается группа, поэтому совпадение 1 - это полное совпадение, а совпадение 2 - это содержимое того, что было найдено в квадратных скобках.

1 голос
/ 16 июня 2011

Groups[0] - вся ваша входная строка.

Groups[1] - это ваша группа в скобках (.*?). Вы можете настроить Regex для захвата только Явных групп (для этого существует опция при создании регулярного выражения) или использовать (?:.*?) для создания группы без захвата.

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