2011-01-19 3 views
2

어떻게 Java가 (Matcher.find()를 사용하여) 가능한 가장 긴 일치를 찾지 못합니까?자바 정규식이 길게 일치하지 않습니다.

regex = "ab*(bc)?" 
정규식 발견 "abbbc" "abbb"의 입력으로

대신 "abbbc"도 일치하고 이상이 중. 가능한 가장 긴 문자열과 일치하도록 강제하는 방법이 있습니까?

답변

1

부분은 왼쪽에서 오른쪽으로 탐욕스럽게 매치합니다. 따라서 b*은 만족스럽고 일치하여 (bc)?이 실패합니다. 따라서 일치 프로그램은 더 이상 b*을 시도하지 않습니다.

아마도 ab*?(?:(?![bc])|(bc))이 원하는대로 수행됩니다.

+0

도움을 주셔서 감사합니다,하지만 이것은 "a"를 반환하는 것과 동일한 문제가있는 것 같습니다. (그러나 "abbbc"는 일치합니까?) 기본적으로 선택적 하위 문자열 (예 : "bc")을 사용하여 일치하는 항목이 있으면이를 포함시키는 방법을 찾고 있습니다. –

+0

@steve 리, 그게 어리 석다. 나는 정규 표현식을 업데이트했다. –

+0

좋아요! 도와 주셔서 감사합니다! –

5

(bc)는 정확한 문자열이므로 b *가 탐욕 스럽기 때문에 발견되지 않았습니다. (bc) 이후?
은 선택 사항이며 마지막 'b'다음에 일치가 성공했습니다. 아마도 다음과 같은 것을 원할 것입니다 : ab*[bc]?하지만이 의미는 아마도 ab*c?입니다. 이 정규식이 좀 더 정교한 것을 나타내면 그 예제를 게시해야합니다. 여기

는 정규식 엔진이 그것을 보는 방법은 다음과 같습니다

Compiling REx "ab*(bc)?" 
Matching REx "ab*(bc)?" against "abbbc" 
    0 <> <abbbc>    | 1:EXACT <a>(3) 
    1 <a> <bbbc>    | 3:STAR(6) 
            EXACT <b> can match 3 times out of 2147483647... 
    4 <abbb> <c>    | 6: CURLYM[1] {0,1}(16) 
    4 <abbb> <c>    | 10: EXACT <bc>(14) 
             failed... 
            CURLYM trying tail with matches=0... 
    4 <abbb> <c>    | 16: END(0) 
Match successful! 

Compiling REx "ab*[bc]?" 
Matching REx "ab*[bc]?" against "abbbc" 
    0 <> <abbbc>    | 1:EXACT <a>(3) 
    1 <a> <bbbc>    | 3:STAR(6) 
            EXACT <b> can match 3 times out of 2147483647... 
    4 <abbb> <c>    | 6: CURLY {0,1}(19) 
            ANYOF[bc] can match 1 times out of 1... 
    5 <abbbc> <>    | 19: END(0) 
Match successful! 
1

기타 정규 표현식을 개선하기 위해 도움이; 그러나 대답을 강조하는 것은 "탐욕적인 일치를하기 때문에"입니다. 즉, 알고리즘에 따라 도달하는 일치입니다 (기본적으로 가능한 가장 긴 부분합은 왼쪽에서 오른쪽으로).

1

표현식이 실제로 그렇게 보이고 그룹화에 신경 쓰지 않으면 ab+c?으로 다시 쓸 수 있습니다.

표현식이 실제로 더 복잡하고 (bc)을 갖는 것이 필수적이라면 다음과 같이 부정적인 미리보기를 사용할 수 있습니다. 나는 마이크 사무엘의 해결책보다 더 우아 할 것이라고 생각합니다 : ab*(?!c)(bc)?.

+0

이 경우 작동합니다. 감사. 비슷한 정규식에 적용하는 방법을 궁금하네요. "[a-z] [a-z] * (? St \.) (St \.)?" 즉, 문자로 시작하고 그 뒤에 하나 이상의 문자가옵니다. 문자열에 마침표가 없거나 "St."이 들어 있습니다. "성" 그것이 존재한다면. –

+0

당신의 솔루션에서 왜 욕심 많은 '*'는 b의 모든 abbb를 소모하지 않습니까? (ab * (bc)와 동일합니까?). 부정적 예측을 추가하면 "bc"를 어떻게 고려할 수 있습니까? (하지만 "bc"일치하지 않으면 실패합니까?) 도움을 주셔서 감사합니다! –

+0

@steve lee, (?! c)는 'c'가 'b'를 따르도록하지 않으므로 1 문자를 역 추적하여 b *가 'b'자체를 보게됩니다. (?! c)가 만족되면, 일치는 (bc)와 일치하는 마지막 'bc'에서 선택됩니까? – sln

관련 문제