실행 후
grep '[a-z]\{22\}' /usr/share/dict/words
출력은 다음과 같습니다
counterrevolutionaries
electroencephalographs
하지만 실행할 때
grep '[^a-z]\{22\}' /usr/share/dict/words
출력이 없습니다.
나는 그것이 다음과 같은 것을 생산할 것으로 예상했습니다.
grep -v '[a-z]\{22\}' /usr/share/dict/words
내 질문은 무엇이 잘못되었으며 그 이유는 무엇입니까?
답변1
[specification]
정렬 요소(로케일 정렬 알고리즘에 정의된 문자 또는 문자 시퀀스일 수 있음(예: GNU 시스템의 헝가리 로케일에서 dzs
및 사이에 정렬된 정렬 요소)) 와 일치합니다.d
e
지정됨놓다.
사양에는 다음이 포함될 수 있습니다.
- (or) 와 같은 범위는 및 사이에 정렬된 요소를
a-z
대조하는 데 사용됩니다[.dzs.]-z
(일반적으로 abcdefghijklmnoprstuvwxyz를 포함하지만 대부분의 로케일에서는 훨씬 더 많은 것을 포함합니다). 또한 POSIX는 POSIX 로케일 이외의 로케일을 지정하지 않기 때문에 이러한 범위가 조합 순서를 기반으로 하는 정도는 구현마다 크게 다릅니다.a
z
- 단일 문자 또는 대조 요소(
x
,[.dsz.]
) - POSIX 문자 클래스
[:alpha:]
,[:digit:]
[=e=]
기본 데이터 정렬 가중치가 동일한 모든 데이터 정렬 요소 와 같은 등가 클래스e
(다음과 같은 항목이 포함될 수 있음é
)
예를 들어 [acd[=e=]h-k[:digit:][.dzs.]]
조합 요소의 일치 항목이 , 또는 a
과 c
같 거나 과 사이에 조합된 경우 분류는 다음과 같습니다 .d
dzs
e
h
k
숫자.
사양이 로 시작하면 ^
여전히 데이터 정렬 요소와 일치하지만 집합을 보완합니다. 이는 지정된 요소가 아닌 모든 데이터 정렬 요소입니다.
따라서 는 및 사이에 정렬되지 않은 [^a-z]
모든 조합 요소와 일치합니다 . 예를 들어 로케일 및 구현에 따라 일치하거나 일치하지 않을 수 있는 및 와 일치할 수 있지만 에서는 일치 하거나 일치 하지 않을 수 있습니다 .a
z
1
ẑ
X
DSZ
grep
a
x
z
é
그래서 grep '[^a-z]\{22\}'
일치하는 라인포함하다데이터 정렬 앞이나 뒤에 오는 22
일련의 조합 요소입니다.a
z
While 은 및 사이에 정렬된 22개의 조합 요소 시퀀스를 포함하지 않는 행 grep -v '[a-z]\{22\}'
과 일치합니다 .a
z
동일한 요소를 일치시키는 것은 거의 불가능합니다. 두 요소 사이에 정렬된 요소가 21개 이하인 줄을 -v
일치시켜야 합니다 . 그러나 로케일이 다중 문자 조합 요소를 지원하는 경우 실제로는 불가능합니다. 예를 들어, 헝가리 로케일에서는 on과 일치 하지만 또한 일치하므로 거기 에서 찾을 수 있습니다. will match on 그러나 또한 일치합니다 .[a-z]
[^a-z]
[a-z]
dsz
d
s
z
[a-z]{0,21}
dszxxxyyyxxxyyyxxxyyyx
[a-z]{22}
다중 문자 조합 요소가 없는 로케일의 경우 다음을 수행할 수 있습니다.
grep '^[^a-z]*\([a-z]\{1,21\}[^a-z]\{1,\}\)*[a-z]\{0,21\}$'
grep
이제 몇 가지 옵션과 함께 고급 정규 구문을 지원하는 구현 도 있습니다.부정적인운영자.
예를 들어, GNU 또는 ast-open 구현은 옵션이 grep
있는 perl 유사(GNU grep의 libpcre, ast-open 자체 ast-open grep 구현) 정규식을 지원합니다.-P
(?!pattern)
부정적인 예측 연산자.
(?!pattern)
패턴이 거기에서 일치하지 않으면 대상 문자열의 어느 지점에서든 너비가 0인 일치가 이루어집니다. 따라서 다음을 사용할 수 있습니다.
grep -P '^(?!.*[a-z]{22})'
뒤에 문자 수가 없고 22 [a-z]
초가 없는 경우 줄의 시작 부분과 일치합니다. 그러나 PCRE(ast-open이 아님)에서는 [a-z]
로케일에 관계없이 abcdefghijklmnopqrstuvwxyz만 일치합니다.
ast-open에는 -X
그들이 말하는 옵션 도 있습니다향상된 정규 표현식. 이러한 향상된 정규 표현식에는 !
사물을 부정하는 연산자가 있습니다. (빈 문자열 포함)을 제외한 모든 항목 x!
과 일치합니다 .x
따라서 ast-open을 사용하면 grep
다음 작업도 수행할 수 있습니다.
grep -X '^(.*[a-z]{22}.*)!$'
답변2
grep '[^a-z]\{22\}' /usr/share/dict/words
/usr/share/dict/words
소문자가 아닌 22자 문자열을 포함 하는 파일의 행을 찾습니다 . 파일에는 그러한 줄이 포함되어 있지 않을 가능성이 높습니다. (이 파일에 문자가 아닌 문자열이 22개 포함된 이유는 무엇입니까?)grep -v '[a-z]\{22\}' /usr/share/dict/words
22자 문자열을 포함하지 않는 줄을 찾습니다. 그러한 줄이 많이 있을 수 있습니다. (대부분의 단어가 22자 미만이기 때문입니다.)