Таким образом, если я пишу regex, это - соответствия, я могу получить соответствие, или я могу получить доступ к его группам. Это кажется счетчиком, интуитивным, так как группы определяются в выражении с фигурными скобками" (" и")". Кажется, что это не только неправильно, но и избыточно. Кто-либо знает почему?
Regex quickCheck = new Regex(@"(\D+)\d+");
string source = "abc123";
m.Value //Equals source
m.Groups.Count //Equals 2
m.Groups[0]) //Equals source
m.Groups[1]) //Equals "abc"
Согласен - это немного странно, но, думаю, на то есть веские причины.
Регулярное выражение Match
само по себе является группой
, которая, в свою очередь, является захватом
.
Но Match.Value
(или Capture.Value
, как есть на самом деле) допустимо только тогда, когда в строке присутствует одно совпадение - если вы сопоставляете несколько экземпляров шаблон, то по определению он не может вернуть все. Фактически - свойство Value
в Match используется для удобства, когда есть только совпадение.
Но чтобы прояснить, где такое поведение передачи всего совпадения в Группы [0]
имеет смысл - рассмотрим этот (надуманный) пример наивного анминификатора кода:
[TestMethod]
public void UnMinifyExample()
{
string toUnMinify = "{int somevalue = 0; /*init the value*/} /* end */";
string result = Regex.Replace(toUnMinify, @"(;|})\s*(/\*[^*]*?\*/)?\s*", "$0\n");
Assert.AreEqual("{int somevalue = 0; /*init the value*/\n} /* end */\n", result);
}
Сопоставление с регулярным выражением сохранит / * * / комментарии в конце оператора, помещая после него новую строку - но работает в любом случае; или} окончания строк.
Хорошо - вы можете задаться вопросом, зачем вам это нужно делать с регулярным выражением - но посмешите меня:)
Если Группы [0]
, сгенерированные совпадениями для этого регулярного выражения, не были всем захватом - тогда замена за один вызов будет невозможна - и ваш вопрос, вероятно, будет спрашивать, почему не все совпадение помещается в Группы [0]
, а не наоборот круглый!
Это все историческое. В Perl 5 содержимое групп захвата хранится в специальных переменных $ 1
, $ 2
и т. Д., Но C #, Java и другие вместо этого хранят их в массиве (или массиве -подобная структура). Чтобы сохранить совместимость с соглашением об именах Perl (которое было скопировано несколькими другими языками), первая группа хранится в элементе номер один, вторая - в элементе два и т. Д. Это оставляет нулевой элемент свободным, так почему бы не сохранить там полное совпадение ?
К вашему сведению, Perl 6 принял новое соглашение, согласно которому первая группа захвата нумеруется нулем вместо единицы. Я уверен, что это не было сделано только для того, чтобы нас разозлить. ;)
В документации для Match
говорится, что первая группа всегда является полным соответствием, поэтому это не деталь реализации.
Скорее всего, вы можете использовать «$ 0» для представления совпадения в выражении подстановки и «$ 1» для совпадения первой группы и т. Д.
Я не думаю, что на самом деле есть другой ответ, кроме того, что тот, кто написал это, выбрал это в качестве детали реализации. Если вы помните, что первая группа всегда будет равна исходной строке, все должно быть в порядке: -)
Обратные ссылки основаны на единице, например. , \ 1
или $ 1
- это первое подвыражение в скобках и так далее. Как изложено, одно сопоставляется с другим без каких-либо размышлений.
Также примечание: m.Groups ["0"]
дает вам всю совпавшую подстроку, поэтому не забудьте пропустить «0»
, если вы повторяете ] regex.GetGroupNames ()
.
Это может быть избыточным, но у него есть несколько хороших свойств.
Например, это означает, что группы захвата работают так же, как и другие механизмы регулярных выражений - первая группа захвата соответствует «1» и так далее.
Не знаю, почему, но если вы используете именованные группы, вы можете установить параметр RegExOptions.ExplicitCapture и это не следует включать источник в первую группу.