( Оновлення : серпень 2011 р. )
Як згадує геофлан у своїй відповіді , Java 7 тепер підтримує названі групи .
tchrist вказує у коментарі, що підтримка обмежена.
Він детально описує обмеження у своїй чудовій відповіді " Помічник Java Regex "
Підтримка групової групи під назвою Java 7 була представлена ще у вересні 2010 року в блозі Oracle .
В офіційному випуску Java 7 конструктами для підтримки названої групи захоплення є:
(?<name>capturing text)
визначити названу групу "ім'я"
\k<name>
для відновлення названої групи "ім'я"
${name}
для посилання на захоплену групу в рядку заміни Матчера
Matcher.group(String name)
повернути захоплений вхідний податок заданою "названою групою".
Іншими альтернативами для попередньої Java 7 були:
( Оригінальна відповідь : січень 2009 р , тепер наступні два посилання розірвані)
Ви не можете посилатися на названу групу, якщо ви не кодуєте власну версію Regex ...
Саме це і зробив Горбуш2 у цій темі .
Regex2
(обмежена реалізація, як знову вказує tchrist , оскільки вона виглядає лише для ідентифікаторів ASCII. tchrist деталізує обмеження як:
тільки мати змогу мати одну названу групу на одне ім’я (над якою ви не завжди маєте контроль!) і не мати змоги використовувати їх для регекс-рекурсії.
Примітка. Ви можете знайти справжні приклади рекурсії в регулярних регексах Perl та PCRE, як зазначено в Regexp Power , специфікаціях PCRE та узгодженні рядків із слайдом збалансованих дужок )
Приклад:
Рядок:
"TEST 123"
RegExp:
"(?<login>\\w+) (?<id>\\d+)"
Доступ
matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login
Замініть
matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____
(витяг з реалізації)
public final class Pattern
implements java.io.Serializable
{
[...]
/**
* Parses a group and returns the head node of a set of nodes that process
* the group. Sometimes a double return system is used where the tail is
* returned in root.
*/
private Node group0() {
boolean capturingGroup = false;
Node head = null;
Node tail = null;
int save = flags;
root = null;
int ch = next();
if (ch == '?') {
ch = skip();
switch (ch) {
case '<': // (?<xxx) look behind or group name
ch = read();
int start = cursor;
[...]
// test forGroupName
int startChar = ch;
while(ASCII.isWord(ch) && ch != '>') ch=read();
if(ch == '>'){
// valid group name
int len = cursor-start;
int[] newtemp = new int[2*(len) + 2];
//System.arraycopy(temp, start, newtemp, 0, len);
StringBuilder name = new StringBuilder();
for(int i = start; i< cursor; i++){
name.append((char)temp[i-1]);
}
// create Named group
head = createGroup(false);
((GroupTail)root).name = name.toString();
capturingGroup = true;
tail = root;
head.next = expr(tail);
break;
}