Các nhóm được đặt tên theo Regex trong Java


173

Theo hiểu biết của tôi, java.regexgói không có hỗ trợ cho các nhóm được đặt tên ( http://www.THER-expressions.info/named.html ) vì vậy có ai có thể chỉ cho tôi một thư viện bên thứ ba không?

Tôi đã xem jregex nhưng bản phát hành cuối cùng của nó là vào năm 2002 và nó không hoạt động với tôi (phải thừa nhận rằng tôi chỉ thử một thời gian ngắn) theo java5.


3
Hiểu biết của bạn là không chính xác. JDK7 xử lý các nhóm được đặt tên.
tchrist

2
@tchrist Năm 2009 không có JDK7.
Alex78191

Câu trả lời:


275

( 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 PCREChuỗ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;
                }

cả hai liên kết ở trên dường như bị phá vỡ?
Jonas

Mã này là lỗi. Nó đang tìm kiếm định danh ASCII. Sai rồi. Nó nên tìm kiếm bất cứ thứ gì mà Java cho phép trong một định danh !!
tchrist

1
Chỉ là FYI vì bạn có vẻ rất có lương tâm, phần giới hạn không phải là quá nhiều về tên ASCII và Unicode vì nó 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.
tchrist

@tchrist: cảm ơn bạn vì sự chính xác này (bao gồm). Tôi cũng đã thêm một liên kết trở lại câu trả lời xuất sắc của bạn trên "Trình trợ giúp Java Regex" (được nâng cấp).
VonC

Không có phương thức matcher.name (int index) cho đối tượng Matcher trong Java ??
ot0


27

Có nhưng nó lộn xộn hack các lớp mặt trời. Có một cách đơn giản hơn:

http://code.google.com.vn/p/named-regapi/

tên-regapi là một trình bao bọc mỏng để triển khai biểu thức chính quy JDK tiêu chuẩn, với mục đích duy nhất là xử lý các nhóm bắt giữ có tên theo kiểu .net: (? ...).

Nó có thể được sử dụng với Java 5 và 6 (thuốc generic được sử dụng).

Java 7 sẽ xử lý các nhóm bắt giữ có tên, vì vậy dự án này không có nghĩa là kéo dài.


1
Quá tệ điều này không thể được sử dụng từ bên trong GWT.
Sakuraba

4
Kiểm tra ngã ba GitHub của dự án này, nó sửa một số lỗi từ bản gốc. Nó cũng được lưu trữ tại Maven Central.
tony19

1
Chỉ là một lời cảnh báo trong trường hợp của tôi, ngã ba tony19 trên Github không hoạt động trên Android kể từ 0.1.8.
Chuck D

2
@RubberMallet, Sự cố dành riêng cho Android hiện đã được khắc phục và sẽ có trong 0.1.9.
tony19

2

Bạn gặp vấn đề gì với jregex ? Nó hoạt động tốt với tôi theo java5 và java6.

Jregex thực hiện công việc tốt (ngay cả khi phiên bản cuối cùng là từ năm 2002), trừ khi bạn muốn chờ javaSE 7 .


2

Đối với những người chạy pre-java7, các nhóm được đặt tên được hỗ trợ bởi joni (cổng Java của thư viện regrec Oniguruma ). Tài liệu còn thưa thớt, nhưng nó đã làm việc tốt cho chúng tôi.
Các nhị phân có sẵn thông qua Maven ( http://reposective.codehaus.org/org/jruby/joni/joni/ ).


Tôi rất quan tâm đến tùy chọn joni được đề cập bởi Ryan ở trên - bạn có đoạn mã nào sử dụng các nhóm chụp có tên không - Tôi đã quản lý để có được kết hợp cơ bản và tìm kiếm để hoạt động chính xác - nhưng tôi không biết tôi sẽ sử dụng phương pháp nào để sử dụng có quyền truy cập vào tên nhóm hoặc để nhận giá trị của ảnh chụp bằng tên nhóm.
malsmith

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.