Ответ 1
Захват и группировка
Захват группы (pattern)
создает группу, которая захватывает свойство.
Связанный с тем, что вы часто можете видеть (и использовать), - это (?:pattern)
, который создает группу без захвата свойства, следовательно, называется не захватывающей группой.
Группа обычно используется, когда вам нужно повторить последовательность шаблонов, например. (\.\w+)+
, или указать, где чередование должно вступить в силу, например. ^(0*1|1*0)$
(^
, затем 0*1
или 1*0
, затем $
) по сравнению с ^0*1|1*0$
(^0*1
или 1*0$
).
Группа захвата, помимо группировки, также записывает текст, сопоставляемый шаблоном внутри группы захвата (pattern)
. Используя ваш пример, (.*):
, .*
соответствует ABC
и :
соответствует :
, а так как .*
находится внутри группы захвата (.*)
, текст ABC
записывается для группы захвата 1.
Номер группы
Весь шаблон определяется как номер группы 0.
Любая группа захвата в шаблоне начинает индексирование с 1. Индексы определяются порядком открывающих круглых скобок групп захвата. В качестве примера здесь представлены all 5 групп захвата в следующем шаблоне:
(group)(?:non-capturing-group)(g(?:ro|u)p( (nested)inside)(another)group)(?=assertion)
| | | | | | || | |
1-----1 | | 4------4 |5-------5 |
| 3---------------3 |
2-----------------------------------------2
Номера групп используются в обратной ссылке \n
в шаблоне и $n
в строке замены.
В других вариантах регулярных выражений (PCRE, Perl) они также могут использоваться в подпрограммах.
Вы можете получить доступ к тексту, сопоставленному определенной группе, с Matcher.group(int group)
. Номера групп можно отождествить с указанным выше правилом.
В некоторых вариантах регулярных выражений (PCRE, Perl) существует функция ветвления reset, которая позволяет использовать то же число для групп захвата в разных ветвях чередования.
Имя группы
Из Java 7 вы можете определить группу захвата (?<name>pattern)
, и вы можете получить доступ к контенту, сопоставляемому с Matcher.group(String name)
. Регулярное выражение длиннее, но код более значим, так как он указывает, что вы пытаетесь совместить или извлекаете с помощью регулярного выражения.
Имена групп используются в обратной ссылке \k<name>
в шаблоне и ${name}
в заменяющей строке.
Именованные группы захвата по-прежнему нумеруются с одинаковой схемой нумерации, поэтому к ним также можно получить доступ через Matcher.group(int group)
.
Внутренне реализация Java просто сопоставляет имя с номером группы. Поэтому вы не можете использовать одно и то же имя для двух разных групп захвата.