2009-12-26 5 views
0

왜이 표현식은 탐욕적인 접근 방식을 따르지 않고 있습니까?왜이 표현식은 탐욕적인 접근 방식을 따르지 않습니까?

string input = @"cool man! your dog can walk on water "; 
string pattern = @"cool (?<cool>(.*)) (?<h>((dog)*)) (?(h)(?<dog>(.*))) "; 

MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace); 


foreach (Match match in matches) 
{ 
    Console.WriteLine("cool=" + match.Groups["cool"].Value); 
    Console.WriteLine("dog=" + match.Groups["dog"].Value); 
    Console.ReadLine(); 
} 

출력 :

 
cool= man! your dog can walk on water 
dog= 

당신이 관찰 할 수 있듯이 : (개) 그룹은 이후 0 짤리을 일치, *은 최대 일치를 찾으려고하지 않는 이유, 욕심 1의 (개)?

실마리가 있습니까?

+0

? 욕심을 제한합니다. –

답변

7

첫 번째 .*은 처음에는 전체 문자열과 일치합니다. 그런 다음 regex 엔진은 정규 표현식의 나머지 부분과 일치시키기 위해 되돌릴 필요가 있는지 여부를 결정합니다. 그러나 (?<h>((dog)*))(?(h)(?<dog>(.*)))은 합법적으로 0 문자와 일치 할 수 있으므로 다시 추적 할 필요가 없습니다 (.*에 관한 한). 그 부분에 욕심 많은 욕구가없는 .*?을 사용해보십시오. (아래의 대답에 게시 된 추가 정보에 응답)

편집 : 좋아, 비 욕심 .*?에 처음 .* 교체, 당신이 원하는 그냥 하나를 효과를 가지고있다. "cool"이라는 단어가 모두 그룹 <cool>에 캡처되기 전에는 이제 그룹 <dog>에 캡처되고 있습니다.

"cool"이라는 단어가 일치하면 (?<cool>(.*?))은 처음에는 아무 것도 (욕심 많은 행동의 반대) 일치하지 않으며 (?<h>((dog)*))은 일치하려고 시도합니다. 이 부분 은 "개"또는 빈 문자열과 일치 할 수 있기 때문에 항상 시도한 위치에 관계없이을 계속 수행합니다. 즉, (?(h)...)의 조건부 표현은 항상 true으로 평가되므로 입력의 나머지 부분은 (?<dog>(.*))과 일치합니다.

내가 이해하는 것처럼 문자열에 "dog"라는 단어가 포함되어 있지 않은 한 명명 된 그룹 <cool>에서 "멋진"다음 항목을 모두 일치 시키려고합니다. 그러면 이름이 바뀐 그룹 <dog>에 "dog"다음의 모든 것을 캡처하려고합니다. conditional을 사용하려하지만 실제로는 올바른 도구가 아닙니다. 그냥이 수행

string pattern = @"cool (?<cool>.*?) (dog (?<dog>.*))?$"; 

여기서 핵심은 마지막에 $이다; 비 탐욕스러운 .*?이 문자열 끝에 도달 할 때까지 계속 일치하도록합니다. 그것은 욕심이 없기 때문에 각 문자를 소비하기 전에 정규 표현식의 다음 부분 인 (dog (?<dog>.*))과 일치 시키려고합니다. "dog"라는 단어가 있으면 나머지 문자열은 (?<dog>.*)에 의해 소비됩니다. 그렇지 않다면 ?이 전체 부분을 선택적으로 만들기 때문에 정규 표현식은 계속 성공합니다.

0

내가 아닌 욕심 (.*?)을 시도 않았지만이 {0,1}에 대한 (.*?) 비 욕심 스탠드로 .and도 제로 문자 여기에 일치하는, 그래서 아무 효과가 있기 때문에 분명 영향을주지 않습니다.

어떻게 해결할 수 있는지 생각해보십시오.나는 내가 이전의 그룹이 문제는 (dog)는 선택 사항이며 현재의 경우, 우리는 그것을 다음과 같은 문자열을 필요로한다는 것입니다 문자열 (cool(.*))

을 캡처 현재의이 또는 다른 경우 (dog) 다음 문자열을 캡처 할, 의미한다.

(dog)?을 사용하면 다시 0 문자와 일치하므로 아무런 영향을 미치지 않습니다.

감사합니다.

+0

비 욕심쟁이 한정어에 대해 잘못된 생각을 가지고 있다고 생각합니다. 이것을 읽으십시오 : http://www.regular-expressions.info/repeat.html 나머지는 내 원래의 대답에 대한 편집을보십시오. –

관련 문제