( Aktualizacja : sierpień 2011 )
Jak geofflane wspomina w swojej odpowiedzi , Java 7 obsługuje teraz nazwane grupy .
tchrist zwraca uwagę w komentarzu, że wsparcie jest ograniczone.
On szczegóły ograniczeń w swej wielkiej odpowiedź „ Java Regex Helper ”
Obsługa grup o nazwie regex Java 7 została zaprezentowana we wrześniu 2010 roku na blogu Oracle .
W oficjalnym wydaniu Java 7 konstrukcje obsługujące nazwaną grupę przechwytującą to:
(?<name>capturing text)
definiowanie nazwanej grupy „nazwa”
\k<name>
odwoływać się do nazwanej grupy „nazwa”
${name}
do odniesienia do przechwyconej grupy w łańcuchu zastępczym Matchera
Matcher.group(String name)
zwraca przechwycony podciąg wejściowy przez daną „nazwaną grupę”.
Inne alternatywy dla wersji przed Java 7 to:
( Oryginalna odpowiedź : styczeń 2009 r. , Kolejne dwa linki są teraz uszkodzone)
Nie możesz odwoływać się do nazwanej grupy, chyba że zakodujesz własną wersję Regex ...
Dokładnie to zrobił Gorbush2 w tym wątku .
Regex2
(ograniczona implementacja, jak wskazał ponownie tchrist , ponieważ szuka tylko identyfikatorów ASCII. tchrist opisuje to ograniczenie jako:
możliwość posiadania tylko jednej nazwanej grupy dla tej samej nazwy (nad którą nie zawsze masz kontrolę!) i niemożność użycia ich do rekurencji w wyrażeniu regularnym.
Uwaga: przykłady prawdziwej rekurencji wyrażeń regularnych można znaleźć w wyrażeniach regularnych Perla i PCRE, jak wspomniano na slajdzie Regexp Power , PCRE specs and Matching Strings with Balanced Nawiasy
Przykład:
Strunowy:
"TEST 123"
RegExp:
"(?<login>\\w+) (?<id>\\d+)"
Dostęp
matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login
Zastąpić
matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____
(wyciąg z realizacji)
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;
}