온라인에서 읽은 내용으로는 sed
겉보기에 게으른 일치로 인해 이해하기 어렵습니다.
에는 ~/tmp/tmp.txt
2개의 탭으로 구분된 3개의 영숫자 문자열이 포함된 줄이 있습니다 TheQuick<TAB>BrownFox<TAB>JumpedOver
. 을 발행하면 sed -n -E '/^.+\t.+\t.+$/p' ~/tmp/tmp.txt
해당 행이 인쇄됩니다.
제 생각에는 정규 표현식이 2개의 탭으로 구분된 3개의 문자열과 일치하더라도 해당 문자열은 영숫자가 아니기 때문에 그렇게 해서는 안 됩니다. 따라서 첫 번째 문자열은 첫 번째 탭과 일치하는 항목을 남기지 않고 해당 줄의 모든 문자를 탐욕스럽게 먹어치워야 합니다.
신뢰할 수 있는 정규식을 만들 수 있도록 이 동작을 어떻게 이해해야 합니까? 저는 GNU를 사용하고 있습니다 sed
.
답변1
탐욕스러운 매칭 시스템은 단순히 가장 큰 것을 찾으려고 노력한다는 것을 의미합니다.성냥문자열(의미첫 번째max에서는 일치하는 문자열이 있더라도 일치하지 않는 문자열에서 중지하는 대신 전체 정규식의 첫 번째 일치에서 검색을 중지합니다. "가능한 가장 일치하는 항목을 찾아주세요. 하지만 나에게 맞는 항목을 반드시 찾으세요!"라는 명령으로 생각하세요. 첫 번째 항목이 .\+
전체 문자열을 먹도록 허용하면 정규식이 일치하지 않는다는 의미이므로 엔진은 돌아가서 다른 것을 시도합니다.
귀하의 경우 정규식을 줄의 시작과 끝( ^
및 $
) 에 고정하므로 .+
정규식에 다른 내용이 있기 때문에 줄의 끝까지 도달할 수 없기 때문에 훨씬 더 간단합니다.
그리디 매칭을 설명하는 데 도움이 될 수 있는 예는 다음과 같습니다.
$ echo aaaaaaa | sed 's/a*/B/'
B
여기서 정규식은 a*
"0개 이상의 연속된 a
문자와 일치"를 의미하므로 탐욕스러운 일치는 가능한 가장 큰 것을 찾습니다.성냥끈. 탐욕스럽지 않은 일치(예: PCRE 사용)는 다음을 반환합니다.
$ echo aaaaaaa | perl -pe 's/a*?/B/'
Baaaaaaa
non-greedy는 가장 긴 문자열 대신 가장 짧은 일치 문자열을 찾기 때문입니다.
영숫자를 언급한 이유나 그것이 어떤 관련이 있는지 이해가 되지 않습니다. 어쩌면 당신은 오해하고 .
영숫자 문자열만 일치할 것이라고 생각했을 수도 있지만, 그렇지 않습니다. .
(사용하는 정규식 스타일과 제공하는 옵션에 따라 개행 문자와도 일치할 수 있습니다.) 영숫자 문자열을 원할 경우 [[:alnum:]]
일치하는 POSIX 문자 클래스를 사용할 수 있습니다 [a-zA-Z0-9]
.