내 임무는 첫 번째 단어가 포함된 egrep 줄을 찾는 것입니다.정확히세 개의 동일한 문자. 역참조를 사용해 보았지만 3개 이상의 동일한 문자로 구성된 단어를 찾는 패턴을 작성하는 방법만 찾았습니다.
egrep -i '^[^[:alpha:]]*\<[a-z]*([a-z])[a-z]*(\1[a-z]*){2}\>'
답변1
다음은 3개의 동일한 [:alpha:] 문자만 포함하는 줄 시작 부분의 모든 "단어"와 일치합니다.
grep -i '^\([[:alpha:]]\)\1\1\b'
또는 grep의 -E
( --extended-regexp
) 또는 -P
(일명 --perl-regexp
) 옵션을 사용하십시오.
grep -iE '^([[:alpha:]])\1\1\b'
grep -iP '^([[:alpha:]])\1\1\b'
이는 GNU grep 및 (버전 제외 -P
) FreeBSD의 grep과 함께 작동합니다. 다른 버전의 grep에서는 작동하지 않을 수 있습니다.
다음을 포함하는 모든 길이의 단어를 일치시키려는 경우3개 이상어디에서나 동일한 알파벳 문자를 사용하는 것은 약간 어렵습니다. 당신은부정적인 예측, Perl 호환 정규 표현식이 필요합니다.
grep -E
즉 egrep
, 사용할 수 없습니다.더 이상 사용되지 않음).
예를 들어:
$ grep -iP '^[[:alpha:]]*([[:alpha:]])((?:(?!\1)[[:alpha:]])*\1){2}[[:alpha:]]*\b' /usr/share/dict/words
Aaliyah
Aaliyah's
Aarau
Aargau
Aaronical
Abadan
Abbottstown
Abbottstown's
Aberdeen
Aberdeen's
...
zoozoo
zoozoos
zuzzes
zwitterionic
zygogeneses
zygomorphous
zymogeneses
zyzzyva
zyzzyvas
zzz
( this 에 따르면 wc -l
이것은 내 /usr/share/dict/words 파일에 있는 344817 단어 중 67117과 일치합니다)
마지막으로 단어만 일치시킵니다.정확히 3어디에서나 동일한 [:alpha:] 문자:
$ grep -iP '^[[:alpha:]]*([[:alpha:]])((?:(?!\1)[[:alpha:]])*\1){2}[[:alpha:]]*\b' /usr/share/dict/words |
grep -viP '^[[:alpha:]]*([[:alpha:]])((?:(?!\1)[[:alpha:]])*\1){3}'
첫 번째 grep은 3개 이상의 동일한 문자가 있는 단어를 찾고, 두 번째 grep은 4개 이상의 동일한 문자가 있는 단어를 제외합니다.
단일 정규식으로 이 작업을 수행할 수 있는지 확실하지 않습니다.
(이것은 내 /usr/share/dict/words 파일의 56820 단어와 일치합니다).
답변2
grep
길이가 0인 어설션 및 역참조와 같은 Perl/PCRE 기능을 사용하더라도 정규식으로는 이 작업을 수행 할 수 없다고 생각합니다 .
이것은 아마도 이론적인 토끼굴일지도 모르지만, 나는 그런 것에는 관심이 없습니다.
따라서 Perl을 사용하여 수행하십시오. "알고리즘"은 awk, Ruby, Python 등으로 쉽게 번역될 수 있습니다.
perl -CiI -anle 'my ($i,%l); ($n=++$l{$_})==3 ? $i++ : $n==4 ? $i-- : () for $F[0]=~/\pL/g; print if $i' file
이는 쉽게 조정할 수 있습니다. 예를 들어, 3개의 글자가 3번 반복되는 단어를 찾으려면 다음과 같이 하세요.
perl -CiI -anle 'my ($i,%l); ($n=++$l{$_})==3 ? $i++ : $n==4 ? $i-- : () for $F[0]=~/\pL/g; print if $i >= 3' /usr/share/dict/words
...
entertainment
...
totalitarianism
또는 7개의 문자가 2번 반복됩니다.
perl -CiI -anle 'my ($i,%l); ($n=++$l{$_})==2 ? $i++ : $n==3 ? $i-- : () for $F[0]=~/\pL/g; print if $i >= 7' /usr/share/dict/words
...
electroencephalograph
...
telecommunication
또한 임의의 문자 \pL
만 일치하도록 변경할 수도 있고 , 전체 줄만 일치하도록 전환하거나 ASCII 문자만 고려하도록 생략하는 등의 작업도 가능합니다..
$F[0]=~/../
/../
-a
-CiI
답변3
가지다아니요ERE(확장 정규식)만을 사용하여 이러한 정규식을 작성하는 방법입니다.
GNU grep(perl regex)에 더 가깝습니다(3개 이상의 반복 문자와 일치):
grep -P '(\w)(((?!\1)\w)*\1){2}' filename
따라서 4번 이상 반복된 단어를 제거하면 답이 나옵니다.
grep -P '(\w)(((?!\1)\w)*\1){2}' filename |
grep -Pv '(\w)(((?!\1)\w)*\1){3}'
GNU awk의 대안은 다음과 같습니다.
awk '{
a=$1;
while (length(a)){
b=gensub(substr(a,0,1),"","g",a);
if(length(a)-length(b)==3){print $0;next};
a=b
}
}' filename
첫 번째 문자의 모든 반복을 제거하여 작동합니다. 제거된 문자가 3자인 경우 인쇄하고, 그렇지 않으면 대체할 문자가 더 이상 없을 때까지 다음 첫 번째 문자를 제거합니다(개선 사항은 남은 길이가 다음과 같은지 또는 같은지 테스트하는 것입니다). 필요한 반복 횟수보다 큼).
A
개수가 동일해지기를 원한다고 가정하고 a
다음을 사용하여 파일을 필터링합니다.
cat /usr/share/dict/words | tr [[:upper:]] [[:lower:]] > words
두 솔루션은 유사하지만 동일하지는 않습니다. independence
위에서 생성된 사전 파일과 같이 두 단어는 단어가 다릅니다.
예, independence
3개가 포함되어 있지만 n
4개가 포함되어 있습니다 e
. 어떤 단어가 먼저 발견되는지에 따라 해당 단어가 포함될 수도 있고 포함되지 않을 수도 있습니다. awk 솔루션은 안정적이며 다음 단어를 포함합니다.어느문자가 정확히 3번 반복됩니다. 정규식 솔루션은 더 유연하며 일부 조건에서는 일치하지만 다른 조건에서는 일치하지 않습니다.
또한 정규식은 다음과만 일치합니다.단어문자가 포함되어 있지 않습니다 '
(파일에 해당 문자가 포함된 여러 단어가 포함되어 있음).
전체적으로 일치하는 행 수는 다음과 같습니다(awk를 사용하면 1527개 추가 행).
13758 awklist
12231 greplist
그리고 삭제합니다 '
(awk를 사용하여 184를 삭제할 수도 있음).
9236 awklist2
9052 greplist2
tastelessness teleconferencing teletypewriter teletypewriters tempestuousness timelessness tintinnabulation tintinnabulations tirelessness transcontinental transgressors transubstantiation
(몇 가지 예를 들자면) 거부되어야 합니까 ?
실제로 모두 존재합니다삼1개의 문자와 4개(또는 그 이상)의 다른 문자입니다.