Java의 정규식 명명 된 그룹 대한 지원이없는 http://www.regular-expressions.info/named.html 않는 타사 라이브러리를

그것은 나의 이해입니다 java.regex패키지라는 이름의 그룹 (에 대한 지원이없는 http://www.regular-expressions.info/named.html 않는 타사 라이브러리를 향해 캔 누구 포인트 나 정도)?

jregex를 살펴 보았지만 마지막 릴리스는 2002 년이며 java5에서는 저에게 효과적이지 않았습니다 (간단히 시도했습니다).



답변

( 업데이트 : 2011 년 8 월 )

으로 geofflane가 에 언급 그의 대답 , 자바 7은 현재라는 이름의 그룹을 지원 .
tchrist 는 의견에서 지원이 제한적이라고 지적합니다.
그는 훌륭한 답변 ” Java Regex Helper ” 의 제한 사항에 대해 자세히 설명합니다.

Java 7 정규식 그룹 지원은 2010 년 9 월 Oracle 블로그에서 다시 발표되었습니다 .

Java 7의 공식 릴리스에서 명명 된 캡처 그룹을 지원하는 구성은 다음과 같습니다.

  • (?<name>capturing text) 명명 된 그룹 “name”을 정의
  • \k<name> 명명 된 그룹 “name”을 역 참조하는 방법
  • ${name} Matcher의 대체 문자열에서 캡처 된 그룹을 참조
  • Matcher.group(String name) 지정된 “명명 된 그룹”에 의해 캡처 된 입력 서브 시퀀스를 리턴합니다.

Java 7 이전의 다른 대안 은 다음과 같습니다.


( 원래 답변 : 2009 년 1 월 , 다음 두 링크가 끊어짐)

자신의 Regex 버전을 코딩하지 않으면 명명 된 그룹을 참조 할 수 없습니다.

그것이 바로이 스레드에서 Gorbush2가 한 일입니다 .

정규식 2

ASCII 식별자 만 찾기 때문에 tchrist가 다시 지적한 제한적인 구현 . tchrist는 다음과 같은 제한 사항을 자세히 설명합니다.

같은 이름마다 하나의 명명 된 그룹 만 가질 수 있으며 (항상 제어 할 수있는 것은 아닙니다!) 정규식 재귀에 사용할 수 없습니다.

참고 : Regexp Power , PCRE 사양균형 괄호가있는 일치 문자열에 언급 된 것처럼 Perl 및 PCRE 정규 표현식에서 실제 정규식 재귀 예제를 찾을 수 있습니다 )

예:

끈:

"TEST 123"

정규식 :

"(?<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;
                }


답변

늦게 오는 사람들을 위해 : Java 7은 명명 된 그룹을 추가합니다. Matcher.group (String groupName) 설명서


답변

그렇습니다.하지만 태양 클래스를 해킹하는 것은 지저분합니다. 더 간단한 방법이 있습니다.

http://code.google.com/p/named-regexp/

named-regexp는 표준 JDK 정규 표현식 구현을위한 씬 래퍼이며 .net 스타일에서 명명 된 캡처 그룹을 처리하는 단일 목적은 (? …)입니다.

Java 5 및 6과 함께 사용할 수 있습니다 (일반이 사용됨).

Java 7은 명명 된 캡처 그룹을 처리하므로이 프로젝트는 지속되지 않습니다.


답변

jregex 어떤 종류의 문제가 있습니까? java5 및 java6에서 저에게 효과적이었습니다.

javaSE 7을 기다리지 않는 한 Jregex는 (마지막 버전이 2002 버전이더라도) 잘 작동합니다 .


답변

java7 이전 버전을 실행하는 사용자의 경우 이름 지정된 그룹은 joni ( Oniguruma regexp 라이브러리 의 Java 포트)에서 지원됩니다 . 문서는 드물지만 우리에게는 잘 작동했습니다.
바이너리는 Maven ( http://repository.codehaus.org/org/jruby/joni/joni/ )을 통해 사용할 수 있습니다 .


답변

조금 오래된 질문이지만 나는 이것을 필요로하고 위의 제안이 부적절하다는 것을 알았습니다. 따라서 얇은 포장지가 직접 개발되었습니다 : https://github.com/hofmeister/MatchIt


답변