( Actualización : agosto de 2011 )
Como geofflane menciona en su respuesta , Java 7 ahora admite grupos con nombre .
tchrist señala en el comentario que el apoyo es limitado.
Se detalla las limitaciones en su gran respuesta " Java Regex Helper "
El soporte de grupo denominado Java 7 regex se presentó en septiembre de 2010 en el blog de Oracle .
En el lanzamiento oficial de Java 7, las construcciones para soportar el grupo de captura nombrado son:
(?<name>capturing text)
para definir un "nombre" de grupo con nombre
\k<name>
hacer referencia a un "nombre" de grupo con nombre
${name}
para hacer referencia al grupo capturado en la cadena de reemplazo de Matcher
Matcher.group(String name)
para devolver la subsecuencia de entrada capturada por el "grupo con nombre" dado.
Otras alternativas para pre-Java 7 fueron:
( Respuesta original : enero de 2009 , con los siguientes dos enlaces ahora rotos)
No puede hacer referencia al grupo con nombre, a menos que codifique su propia versión de Regex ...
Eso es precisamente lo que hizo Gorbush2 en este hilo .
Regex2
(implementación limitada, como lo señaló nuevamente tchrist , ya que solo busca identificadores ASCII. tchrist detalla la limitación como:
solo poder tener un grupo con nombre por el mismo nombre (¡sobre el cual no siempre tienes control!) y no poder usarlos para la recursividad en expresiones regulares.
Nota: Puede encontrar ejemplos de recursividad de expresiones regulares verdaderas en expresiones regulares de Perl y PCRE, como se menciona en Regexp Power , especificaciones de PCRE y diapositivas de Correspondencia con paréntesis equilibrados )
Ejemplo:
Cuerda:
"TEST 123"
RegExp:
"(?<login>\\w+) (?<id>\\d+)"
Acceso
matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login
Reemplazar
matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____
(extracto de la implementación)
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;
}