word-grep의 동일한 문자의 정확한 수

word-grep의 동일한 문자의 정확한 수

내 임무는 첫 번째 단어가 포함된 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 -Eegrep, 사용할 수 없습니다.더 이상 사용되지 않음).

예를 들어:

$ 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위에서 생성된 사전 파일과 같이 두 단어는 단어가 다릅니다.

예, independence3개가 포함되어 있지만 n4개가 포함되어 있습니다 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개(또는 그 이상)의 다른 문자입니다.

관련 정보