난 당신이 후있어 의심 무엇 : 여기
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)은 여러 가지 방법으로 처리 할 수 있습니다. 위의 내 접근 방식은 너비가 0이므로 \ b를 사용하는 것이 훨씬 더 나은 해결책입니다.
<?<=\W|^)...(?=\W|$)
을하지만 기본적으로 동등한입니다 : 당신은 또한 lookaheads 및 lookbehinds 같은 다른 제로 폭 주장을 사용할 수 읽기 훨씬 쉽게
\b...\b
.
(2)는 구를 인용하여 처리 할 수 있습니다. 위 코드를 수정하여 정규식 특수 문자를 인용하기 위해 Pattern.quote()
을 호출했습니다.
정확히 내가하고 있었던 것. 그러나 구가 처음이나 끝에 괄호를 포함하면 문제가 발생합니다. 그게 내가 \ W를 대신 사용했던 이유입니다. – Eqbal
구문에 괄호가 포함 된 경우 구문이 무엇인지 정의하고 정확히 구분해야합니다. – cletus
'\ b ... \ b'은 구문에서 특수 문자를 이스케이프 처리 한 후에도 작동하지 않습니다. 다음은 작동하는 것으로 보이는 업데이트 된 정규식입니다. "(^ | \\ b | \\ W) ("+ ORedPhrases + ") (\\ W | $)"' – Eqbal