IT이야기

Java에서의 Regex 이름 있는 그룹

cyworld 2022. 6. 14. 22:42
반응형

Java에서의 Regex 이름 있는 그룹

제가 알기로는java.regex패키지는 이름 있는 그룹(http://www.regular-expressions.info/named.html)을 지원하지 않습니다.따라서 서드파티 라이브러리로 안내해 주실 수 있나요?

jregex는 2002년에 발매된 것을 확인했습니다만, java5에서는 동작하지 않았습니다.

(갱신:2011년 8월)

답변에서 geofflane이 언급했듯이, Java 7은 이제 명명된 그룹을 지원합니다.
tchrist는 코멘트에서 지원이 제한적이라고 지적합니다.
그는 그훌륭한 답변인 "Java Regex Helper"에서 한계를 자세히 설명합니다.

Java 7 regex라는 이름의 그룹 지원은 2010년 9월에 Oracle 블로그에 소개되었습니다.

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

  • (?<name>capturing text)이름 있는 그룹을 정의하다
  • \k<name>명명된 그룹 "name"을 역참조하다
  • ${name}Matcher의 대체 문자열에서 캡처된 그룹을 참조합니다.
  • Matcher.group(String name) 지정된 "named group"에 의해 캡처된 입력 시퀀스를 반환합니다.

Java 7 이전 버전의 다른 대안으로는 다음이 있습니다.


(원래 답변: 2009년 1월, 다음 2개의 링크가 끊어졌습니다)

자신의 Regex 버전을 코드화하지 않는 한 명명된 그룹을 참조할 수 없습니다.

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

정규식 2

(tchrist가 다시 지적한 바와 같이 제한적인 구현은 ASCII 식별자만 검색하기 때문에 제한에 대한 자세한 내용은 다음과 같습니다.

같은 이름당 하나의 이름 있는 그룹만 가질 수 있고(항상 제어할 수 있는 것은 아닙니다!) regex 내 재귀에 사용할 수 없습니다.

주의: Regexp Power, PCRE 사양균형 괄호를 사용한 매칭 문자열 슬라이드에 기재된 바와 같이 Perl 및 PCRE 정규식에서 regex의 진정한 재귀 예를 찾을 수 있습니다.)

예:

문자열:

"TEST 123"

RegExp:

"(?<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에서 잘 작동했어요.

jregex는 javaSE 7을 기다리는 것을 원하지 않는 한 (마지막 버전이 2002년 버전인 경우에도) 작업을 잘 수행합니다.

pre-java7을 실행하고 있는 사용자의 경우 이름 있는 그룹은 joni(Oniguruma regexp 라이브러리의 Java 포트)에서 지원됩니다.서류는 희박하지만 우리에게도 잘 작동했습니다.
바이너리는 Maven(http://repository.codehaus.org/org/jruby/joni/joni/)에서 이용할 수 있습니다.

조금 오래된 질문이지만, 저도 이 질문이 필요하다는 것을 알게 되었습니다.상기의 제안은 불충분하고, 그래서 얇은 포장지를 스스로 개발했습니다.https://github.com/hofmeister/MatchIt

언급URL : https://stackoverflow.com/questions/415580/regex-named-groups-in-java

반응형