( Cập nhật : tháng 8 năm 2011 )
Như geofflane đề cập trong câu trả lời của mình , Java 7 hiện hỗ trợ các nhóm được đặt tên .
tchrist chỉ ra trong nhận xét rằng sự hỗ trợ bị hạn chế.
Ông nói chi tiết về những hạn chế trong câu trả lời tuyệt vời của mình " Trình trợ giúp Java Regex "
Regex Java 7 có tên hỗ trợ nhóm đã được trình bày lại vào tháng 9 năm 2010 trên blog của Oracle .
Trong bản phát hành chính thức của Java 7, các cấu trúc để hỗ trợ nhóm bắt giữ có tên là:
(?<name>capturing text)
để xác định một nhóm "tên" được đặt tên
\k<name>
để phản ứng lại một nhóm có tên "tên"
${name}
để tham chiếu đến nhóm bị bắt trong chuỗi thay thế của Matcher
Matcher.group(String name)
để trả về chuỗi đầu vào bị bắt bởi "nhóm được đặt tên" đã cho.
Các lựa chọn thay thế khác cho tiền Java 7 là:
( Câu trả lời gốc : Tháng 1 năm 2009 , với hai liên kết tiếp theo hiện đã bị hỏng)
Bạn không thể tham khảo nhóm được đặt tên, trừ khi bạn viết mã phiên bản Regex của riêng mình ...
Đó chính xác là những gì Gorbush2 đã làm trong chủ đề này .
Regex2
(triển khai hạn chế, như được chỉ ra một lần nữa bởi tchrist , vì nó chỉ tìm các định danh ASCII. tchrist nêu chi tiết giới hạn như:
chỉ có thể có một nhóm được đặt tên cho cùng một tên (mà bạn không luôn có quyền kiểm soát!) và không thể sử dụng chúng cho đệ quy in-regex.
Lưu ý: Bạn có thể tìm thấy các ví dụ đệ quy regex thực trong các biểu thức regl và PCRE, như đã đề cập trong Regapi Power , thông số kỹ thuật PCRE và Chuỗi kết hợp với slide ngoặc đơn cân bằng )
Thí dụ:
Chuỗi:
"TEST 123"
RegExp:
"(?<login>\\w+) (?<id>\\d+)"
Truy cập
matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login
Thay thế
matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____
(trích từ thực hiệ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;
}