Ответ 1
(Обновить: Август 2011)
В качестве geofflane упоминается его ответ, Java 7 теперь поддерживает именованные группы.
tchrist указывает в комментарии, что поддержка ограничена.
Он детализирует ограничения в своем замечательном ответе Java Regex Helper"
Поддержка Java 7 regex с именем group была представлена в сентябрь 2010 в блоге Oracle.
В официальном выпуске Java 7 конструкциями, поддерживающими названную группу захвата, являются:
(?<name>X)
для определения имени именованной группы "\k<name>
для обратной ссылки названная группа" name "${name}
для ссылки на захваченную группу в строке замены MatcherMatcher.group(String name)
, чтобы вернуть захваченную входную подпоследовательность заданной" именованной группе ".
Другие альтернативы для pre-Java 7:
- Google named-regex (см. Джон Харди ответ)
Gábor Lipták упоминает (ноябрь 2012 г.), что этот проект может быть неактивным (с несколько выдающихся ошибок), и вместо этого можно было бы рассмотреть его вилку GitHub. - jregex (см. Брайан Клозел ответ)
( Оригинальный ответ: январь 2009, со следующими двумя сломанными слотами)
Вы не можете ссылаться на именованную группу, если вы не указали свою собственную версию Regex...
Именно это Gorbush2 сделал в этом потоке.
(ограниченная реализация, о чем еще раз отметили tchrist, поскольку она выглядит только для идентификаторов ASCII. tchrist указывает ограничение как:
может иметь только одну именованную группу для одного и того же имени (к которой вы не всегда имеете контроль!) и не можете использовать их для рекурсии в регулярном выражении.
Примечание. Примеры верных регулярных выражений можно найти в регулярных выражениях Perl и PCRE, как указано в Regexp Power, спецификации PCRE и Сопоставление строк со сбалансированными круглыми скобками)
Пример:
String
"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;
}