2011-08-04 4 views
21

항목은 하나 이상의 숫자 또는 문자로 구성된 콤마로 구분 된 목록입니다.자바 정규식 : 캡처 그룹 반복

예를 들어 Java에서 0 개 이상의 괄호로 묶은 목록을 찾으려고합니다.

"" 
"(12)" 
"(abc,12)" 
"(abc,12),(30,asdf)" 
"(qqq,pp),(abc,12),(30,asdf,2)," 
I는 다음과 일치하는 다음의 (잘못된) 패턴

\((.+?)\)(?:,\((.+?)\))* 

을 마련했습니다

qqq,pp 
abc,12 
30,asdf,2 

마지막 예를 들어 각각 다음과 일치하는 그룹을 반환해야

마지막 예를 들면

qqq,pp 
30,asdf,2 

팁? 감사합니다.

+2

문자열을 ")," "로 분리하고 결과를 얻기 위해 나머지 괄호를 제거 할 수 있습니까? – Jens

+0

확실히 ['Matcher.find()'] (http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#find())가 필요합니다. – Qix

답변

33

맞아요. Java 정규 표현식에서는 "가변"수의 캡처 그룹을 가질 수 없습니다. 각 그룹은 해당 그룹의 마지막 경기의 내용이 포함됩니다

\((.+?)\)(?:,\((.+?)\))* 
    |___|  |___| 
group 1  group 2 

: 귀하의 패턴은 두 그룹이있다. 즉, abc,1230,asdf,2에 의해 무시됩니다.

관련 질문 :

솔루션 하나 개의 표현 (\((.+?)\) 같은)를 사용하고 일치 반복하는 matcher.find을 사용하는 것입니다.

+0

Argh ok 덕분에 나는 그것을 모른다. 이제는 대안을 찾아야한다. –

+0

그래. 확실히 성가시다. .net은 (내가 링크 된 질문/답변에서 볼 수 있듯이) 기능을 가지고 있습니다. – aioobe

+5

@David, 당신이 그것을 놓친 경우에, 그는 이미 당신에게 좋은 대안을주었습니다 :) – Svish

2

루프에 ([^,]+)과 같은 정규 표현식을 사용하거나 str.split(",")을 사용하면 모든 요소를 ​​한꺼번에 가져올 수 있습니다. 이 버전 : str.split("\\s*,\\s*")도 공백을 허용합니다.

0

이 해결책이 될 수있다 : (| \ S + ^) (\ S *)

package com.drl.fw.sch; 

import java.util.regex.Pattern; 

public class AngularJSMatcher extends SimpleStringMatcher { 

Matcher delegate; 


public AngularJSMatcher(String lookFor){ 
    super(lookFor); 
    // ng-repeat 
    int ind = lookFor.indexOf('-'); 
    if(ind >= 0){ 
     StringBuilder sb = new StringBuilder(); 
     boolean first = true; 
     for (String s : lookFor.split("-")){ 
      if(first){ 
       sb.append(s); 
       first = false; 
      }else{ 
       if(s.length() >1){ 
        sb.append(s.substring(0,1).toUpperCase()); 
        sb.append(s.substring(1)); 

       }else{ 
        sb.append(s.toUpperCase()); 
       } 
      } 
     } 
     delegate = new SimpleStringMatcher(sb.toString()); 
    }else { 
     String words[] = lookFor.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])"); 
     if(words.length > 1){ 
      StringBuilder sb = new StringBuilder(); 
      for (int i=0;i < words.length;i++) { 
       sb.append(words[i].toLowerCase()); 
       if(i < words.length-1) sb.append("-"); 
      } 
      delegate = new SimpleStringMatcher(sb.toString()); 
     } 

    } 

} 

@Override 
public boolean match(String in) { 
    if(super.match(in)) return true; 
    if(delegate != null && delegate.match(in)) return true; 

    return false; 
} 

public static void main(String[] args){ 
    String lookfor="ngRepeatStart"; 

    Matcher matcher = new AngularJSMatcher(lookfor); 

    System.out.println(matcher.match("<header ng-repeat-start=\"item in items\">")); 
    System.out.println(matcher.match("var ngRepeatStart=\"item in items\">")); 

} 

}

1

(($ | \ S +) \ 2) +와 소문자 무시 옵션/I

그녀는 지금

예를 여기 좌측 좌측 좌측 - https://regex101.com/r/FEmXui/2

Match 1 
Full match 3-23 ` left LEft leFT LEFT` 
Group 1. 3-4 ` ` 
Group 2. 4-8 `left` 
Group 3. 18-23 ` LEFT` 
Group 4. 18-19 ` `