私の使命は、最初の単語を含むegrep行を見つけることです。正確に3つの同じ文字。私は逆参照を試しましたが、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つ以上の同じ文字を持つ単語を探し、2番目のgrepは4つ以上の同じ文字を持つ単語を除外します。
単一の正規表現でこれを実行できるかどうかはわかりません。
(これは私の/usr/share/dict/wordsファイルの56820ワードと一致します)。
答え2
grep
長さがゼロのアサーションや逆参照などの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
上記で作成された辞書ファイルのように、2つの単語は単語が異なります。
はい、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つ(またはそれ以上)の異なる文字です。