В регулярном выражении C#, почему начальная буква подходит шоу в группах?

Таким образом, если я пишу 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"
13
задан QueueHammer 11 February 2010 в 22:22
поделиться

8 ответов

Согласен - это немного странно, но, думаю, на то есть веские причины.

Регулярное выражение 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] , а не наоборот круглый!

5
ответ дан 2 December 2019 в 00:58
поделиться

Это все историческое. В Perl 5 содержимое групп захвата хранится в специальных переменных $ 1 , $ 2 и т. Д., Но C #, Java и другие вместо этого хранят их в массиве (или массиве -подобная структура). Чтобы сохранить совместимость с соглашением об именах Perl (которое было скопировано несколькими другими языками), первая группа хранится в элементе номер один, вторая - в элементе два и т. Д. Это оставляет нулевой элемент свободным, так почему бы не сохранить там полное совпадение ?

К вашему сведению, Perl 6 принял новое соглашение, согласно которому первая группа захвата нумеруется нулем вместо единицы. Я уверен, что это не было сделано только для того, чтобы нас разозлить. ;)

2
ответ дан 2 December 2019 в 00:58
поделиться

В документации для Match говорится, что первая группа всегда является полным соответствием, поэтому это не деталь реализации.

4
ответ дан 2 December 2019 в 00:58
поделиться

Скорее всего, вы можете использовать «$ 0» для представления совпадения в выражении подстановки и «$ 1» для совпадения первой группы и т. Д.

1
ответ дан 2 December 2019 в 00:58
поделиться

Я не думаю, что на самом деле есть другой ответ, кроме того, что тот, кто написал это, выбрал это в качестве детали реализации. Если вы помните, что первая группа всегда будет равна исходной строке, все должно быть в порядке: -)

0
ответ дан 2 December 2019 в 00:58
поделиться

Обратные ссылки основаны на единице, например. , \ 1 или $ 1 - это первое подвыражение в скобках и так далее. Как изложено, одно сопоставляется с другим без каких-либо размышлений.

Также примечание: m.Groups ["0"] дает вам всю совпавшую подстроку, поэтому не забудьте пропустить «0» , если вы повторяете ] regex.GetGroupNames () .

0
ответ дан 2 December 2019 в 00:58
поделиться

Это может быть избыточным, но у него есть несколько хороших свойств.

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

0
ответ дан 2 December 2019 в 00:58
поделиться

Не знаю, почему, но если вы используете именованные группы, вы можете установить параметр RegExOptions.ExplicitCapture и это не следует включать источник в первую группу.

0
ответ дан 2 December 2019 в 00:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: