2011-02-15 2 views
0

문자열을 검색하여 특정 패턴과 일치하는 문자열을 검색하려고합니다. 그런 다음 쉼표로 구분 된 발견 된 문자열의 고유 목록을 작성합니다. 해당 패턴이 "#LOOKING()" 또는 "/* */"이 아니고 _something 부분에 다른 특수 문자가없는 한 패턴은 "$FOR_something"입니다. 예를 들어문자열 내에서 문자열 패턴을 식별하는 방법은 일치하지만 일치하는 패턴이 식별 된 패턴 안에있는 경우 무시하는 방법

,이 문자열 발견 패턴 내가 위의 인용 문자열이 될 것이다에서 찾고 있어요의

"Not #LOOKING($FOR_one $FOR_two) /* $FOR_three */ not $$$FOR_four or $FOR_four_b, but $FOR_five; and $FOR_six and not $FOR-seven or $FOR_five again" 

결과 목록이있는 경우 :

$FOR_five, $FOR_six 

내가이 시작을 예 :

import java.lang.StringBuffer; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 
public class testIt { 
public static void main(String args[]) { 

String myWords = "Not #LOOKING($FOR_one $FOR_two) /* $FOR_three */ not $$$FOR_four or $FOR_four_b, but $FOR_five; and $FOR_six and not $FOR-seven or $FOR_five again"; 

StringBuffer sb = new StringBuffer(0); 

if (myWords.toUpperCase().contains("$FOR")) 
{ 
    Pattern p = Pattern.compile("\\$FOR[\\_][a-zA-Z_0-9]+[\\s]*", Pattern.CASE_INSENSITIVE); 
    Matcher m = p.matcher(myWords); 

    String myFors = ""; 
    while (m.find()) 
    { 
     myFors = myWords.substring(m.start() , m.end()).trim(); 
     if (sb.length() == 0) sb = sb.append(myFors); 
     else 
     { 
     if (!(sb.toString().contains(myFors))) sb = sb.append(", " + myFors); 
     } 
    } 
} 
System.out.println(sb); 
} 

} 

그러나 내가 원하는 것을 제공하지 않습니다. 내가 원하는 것은 :

$FOR_five, $FOR_six 

대신 $ FOR_somethings가 모두 있습니다. /**/ 또는 #LOOKING()의 발생을 무시하는 방법을 모르겠습니다. 제안 사항이 있으십니까?

답변

0

이 문제는 정규식을 뛰어 넘습니다. $$$ 패턴은 부정적인 lookbehind로 고정 될 수 있고 다른 패턴은 쉽게되지 않을 수 있습니다.

토큰 화/수동 문자열 구문 분석을 사용하여 바람직하지 않은 데이터 (예 : /* ... */ 또는 #LOOKING(....))를 삭제하는 것이 좋습니다.

(?<!\\$)\\$FOR_\\p{Alnum}+(?=[\\s;]) 

설명 :

myWords.replaceAll("/\\*[^*/]+\\*/", "");  // removes /* ... */ 
myWords.replaceAll("#LOOKING\\([^)]+\\)", ""); // removes #LOOKING(...) 

은 일단 당신이 e..g, 다음과 같은 정규 표현식 사용할 수있는 컨텍스트 기반 콘텐츠의 제거 : 이것은 그러나 또한 같은 다른 정규식에 의해 제거 될 수

(?<!\\$)   // Match iff not prefixed with $ 
\\$FOR_   // Matches $FOR_ 
\\p{Alnum}+  // Matches one or more alphanumericals [a-zA-Z0-9] 
(?=[\\s;])  // Match iff followed by space or ';' 

사용 된 (?...)은 결과 자체에서 캡처되지 않는 lookahead/lookbehind 표현식으로 알려져 있음에 유의하십시오. 위의 샘플에서는 접두사/접미사 조건으로 만 작동합니다.

관련 문제