Регулярные группы выражений в С#
Я унаследовал блок кода, который содержит следующее регулярное выражение, и я пытаюсь понять, как он получает его результаты.
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?
Рассматривая этот вопрос из того, что я понимаю, коллекция групп хранит весь матч, а также предыдущий матч. Но, не соответствует ли regexp выше только для [open square bracket] [text] [close square bracket], так почему бы "jsmith" соответствовать?
Кроме того, всегда ли коллектив групп будет хранить ровно 2 группы: полное совпадение и последнее совпадение?
Ответы
Ответ 1
( )
действует как группа захвата. Таким образом, массив совпадений имеет все совпадения, которые С# находит в вашей строке, а в подвале - значения групп захвата внутри этих совпадений. Если вам не нужен этот дополнительный уровень захвата, удалите ( )
.
Ответ 2
-
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]
Ответ 3
Скобка также идентифицирует группу, так что совпадение 1 - это полное совпадение, а совпадение 2 - содержимое того, что было найдено между квадратными скобками.
Ответ 4
Как? Ответ здесь
(.*?)
Это подгруппа в @"[(. *?)];
Ответ 5
Groups[0]
- это вся ваша входная строка.
Groups[1]
- это ваша группа в скобках (.*?)
. Вы можете настроить Regex для захвата только явных групп (для этого существует опция при создании регулярного выражения) или использовать (?:.*?)
Для создания группы без захвата.