2010-01-06 4 views
0

주어진 문자열의 문구 집합에서 일부 또는 전체를 찾으려고합니다. 내가 OR ING입니다Java 정규식 논리 OR

(^|\\W)(" + phrase1 + "|" + phrase2 + "|" + phrase3 + ... ")(\\W|$) 

나는 문구의 수와 일치 할 수 있어야한다 : 여기 내 정규 표현식입니다. 두 문구가 바로 옆에있을 때를 제외하고는 아무 문제없이 작동하는 것 같습니다. 따라서 "phrase1 lorem ipsum phrase2 lorem ipsum"은 phrase1과 phrase2와 일치하지만 "phrase1 phrase2 lorem ipsum"은 phrase1과 일치합니다 ("phrase1.phrase2 lorem ipsum"도 마찬가지입니다). phrase1과 phrase2 사이에 단어가 아닌 문자가 두 개 이상 (예 : 두 개 이상의 공백) 있으면 둘 다 일치합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

답변

1

정규 표현식의 양쪽에 \\W이 있기 때문입니다. 즉, 첫 번째 단어가 아닌 첫 번째 문자가 첫 번째 문자와 일치하고 두 번째 문자가 아닌 문자가 하나 더 필요합니다.

1

난 당신이 후있어 의심 무엇 : 여기

List<String> findPhrases(String s, String... phrases) { 
    return findPhrases(s, Arrays.asList(phrases)); 
} 

List<String> findPhrases(String s, Collection<String> phrases) { 
    if (phrases.size() < 1) { 
    throw new IllegalArgumentException("must specify at least one phrase"); 
    } 
    StringBuilder sb = new StringBuilder(); 
    Iterator<String> iter = phrases.iterator(); 
    String first = iter.next(); 
    sb.append(first); 
    while (iter.hasNext()) { 
    sb.append("|"); 
    sb.append(iter.next()); 
    } 
    Pattern p = Pattern.compile("\\b(" + sb.toString() + ")\\b"); 
    Matcher m = p.matcher(s); 
    List<String> ret = new ArrayList<String>(); 
    while (m.find()) { 
    ret.append(Pattern.quote(m.group(1))); 
    } 
    return ret; 
} 

한 가지 중요한 차이는 단어를 구분하는 W 내가 \보다는 B \ 사용한 적이 있다는 것입니다. \ b는 문자열의 시작, 문자열의 끝 또는 단어 문자에서 단어가 아닌 문자로의 전환에 대한 폭이 0 인 일치입니다.

너비가 0이면 \ W처럼 입력 문자를 사용하지 않는다는 의미입니다.

편집 : 두 가지 문제가 발생하는 것 : W \

  1. 사용자의 입력에서 문자가 소모됩니다;
  2. 구문에 정규식 특수 문자가 있습니다.

(1)은 여러 가지 방법으로 처리 할 수 ​​있습니다. 위의 내 접근 방식은 너비가 0이므로 \ b를 사용하는 것이 훨씬 더 나은 해결책입니다.

<?<=\W|^)...(?=\W|$) 

을하지만 기본적으로 동등한입니다 : 당신은 또한 lookaheads 및 lookbehinds 같은 다른 제로 폭 주장을 사용할 수 읽기 훨씬 쉽게

\b...\b 

.

(2)는 구를 인용하여 처리 할 수 ​​있습니다. 위 코드를 수정하여 정규식 특수 문자를 인용하기 위해 Pattern.quote()을 호출했습니다.

+0

정확히 내가하고 있었던 것. 그러나 구가 처음이나 끝에 괄호를 포함하면 문제가 발생합니다. 그게 내가 \ W를 대신 사용했던 이유입니다. – Eqbal

+0

구문에 괄호가 포함 된 경우 구문이 무엇인지 정의하고 정확히 구분해야합니다. – cletus

+0

'\ b ... \ b'은 구문에서 특수 문자를 이스케이프 처리 한 후에도 작동하지 않습니다. 다음은 작동하는 것으로 보이는 업데이트 된 정규식입니다. "(^ | \\ b | \\ W) ("+ ORedPhrases + ") (\\ W | $)"' – Eqbal