2012-11-16 4 views
1

나는자바 regexp에서 greedy 수량 한정자 X *를 사용할 때 X를 모두 유지하는 방법은 무엇입니까?

내가 괄호 사이의 각 단어를 유지하기 위해 그룹을 캡처 사용하려면 내가 예에서 "Hello <a1> sqjsjqk <b1,b2> dsjkfjkdsf <c1,c2,c3> ffsd" 같은 문자열 내부 < 사이에 혼수 상태로 구분 된 단어 목록의 일치>를 찾는 데 사용할 정규 표현식을 다음은

내 표현 : < (\w+) (?: ,(\w+) )* > (공백 가독성을 위해 첨가되지만, 패턴의 일부가 아닌)

괄호 I가 없기 때문에 캡처 그룹 만들기 위해 (?: )가 비 캡처 그룹을 만들기위한 것입니다 혼수 상태를 유지하고 싶다.

== Match == 
    a1 
    null 
== Match == 
    b1 
    b2 
== Match == 
    c1 
    c3 

그리고 여기가 내가 원하는 무엇인가 :이 생성되는 출력은

@Test 
public void test() { 
    String patternString = "<(\\w+)(?:,(\\w+))*>"; 
    Pattern pattern = Pattern.compile(patternString); 
    Matcher matcher = pattern.matcher("Hello <a1> sqjsjqk <b1,b2> dsjkfjkdsf <c1,c2,c3> ffsd"); 
    while(matcher.find()) { 
     System.out.println("== Match =="); 
     MatchResult matchResult = matcher.toMatchResult(); 
     for(int i = 0; i < matchResult.groupCount(); i++) { 
      System.out.println(" " + matchResult.group(i + 1)); 
     } 
    } 
} 

: 여기

내 테스트 코드이에서

== Match == 
    a1 
== Match == 
    b1 
    b2 
== Match == 
    c1 
    c2 
    c3 

내가 이해가 내 표현의 캡쳐 그룹 수와 정확히 같은 수의 그룹이지만, 원하는 모든 것이 아니기 때문에 원하는 것은 아닙니다. \w+

로 인식되었다 그는 문자열은 하나의 정규식으로 내가 원하는 것을 얻을 수있는 기회가 있는가, 아니면 내가 아는 한 ... split(","), trim() 등으로

답변

2

을 작업을 완료한다 .NET은 유일한 정규식 엔진을 가지고있어 단일 캡처 그룹에 대해 여러 캡처를 반환 할 수 있습니다. 그래서 당신이 요구하는 것은 자바에서 가능하지 않습니다 (최소한 당신이 요구 한 방식이 아닙니다).

그러나이 문제는 어느 정도 해결할 수 있습니다.

"\\w+(?=(?:,\\w+)*>)" 

이 "단어를 일치하지 않을 수 있습니다 : 당신은 타의 추종을 불허하는 폐쇄 >가 결코 확신 할 수 있다면, 당신은 당신이 전체 경기를 캡처 할, 그리고 lookahead를 통해 정확한 위치를 필요로하는 물건을 만들 수 있습니다 " 외부의 경우 < 개구부를 지나서 >과 일치하지 않을 수 있기 때문에 물론 <...> 세트의 요소를 구별하기가 어렵습니다.

또는 (더 안전하고 읽기 쉽기 때문에 더 좋을 것이라고 생각합니다.) 2 단계 알고리즘으로 이동하십시오. 첫 경기

"<([\\w,]*)>" 

그런 split,에서 모든 결과의 첫 번째 캡처.

+0

나는 "더 읽기 쉽다"라는 이유로 옵션 2를 택할 것입니다. 감사합니다 –

+0

@ SamuelRossille 언급했다;) –

관련 문제