
入力ファイルは、複数の10文字の組み合わせを含む行の外側にあります。
NGNAEAREAX EAHVSELYCI FNWGNLACQM AWKLRMDHIT PRYMFNYMVM
NCNREDEEEQ EAHVSELYCI FNWGNLACQM AWKLRMDHIT PRYMFNYMVM
最初の単語に「REGEX」という単語を構成する文字を含むすべての行を見つけるには、正規表現(PCREまたはBRE / ERE)が必要です。したがって、行の最初の単語には少なくともR 1、E 2、G 1、X 1が含まれている必要があります。
したがって、上記の結果は次のようになります。
NGNAEAREAX EAHVSELYCI FNWGNLACQM AWKLRMDHIT PRYMFNYMVM
答え1
単一の正規表現と一致させることはできません(*)。最終的な真または偽の結果を得るには、各条件(R 1、E 2、G 1、X 1)を個別に論理的にANDして一緒にテストする必要があります。
たとえば、次のようにしますawk
。
$ awk '$1 ~ /R/ && $1 ~ /E.*E/ && $1 ~ /G/ && $1 ~ /X/' inputfile.txt
NGNAEAREAX EAHVSELYCI FNWGNLACQM AWKLRMDHIT PRYMFNYMVM
(*) 次の代替項目を使用して正規表現を作成できます。すべて5文字(R、E、G、E、X)の可能な組み合わせは異なる順序で表示されますが、これは非現実的です。
しかし、大文字と小文字を区別しない一致が必要で、GNU awkを使用している場合:
$ awk -v IGNORECASE=1 '$1 ~ /R/ && $1 ~ /E.*E/ && $1 ~ /G/ && $1 ~ /X/' inputfile.txt
または、GNU awkなしで大文字と小文字を区別しません。
$ awk '$1 ~ /[Rr]/ && $1 ~ /[Ee].*[Ee]/ && $1 ~ /[Gg]/ && $1 ~ /[Xx]/' inputfile.txt
答え2
使用幸せ(以前のPerl_6)
~$ raku -e 'for lines() {my %h; for .words.[0].comb() { %h{$_}++ }; \
.put if %h.keys.contains( "R" & "E" & "G" & "X") && %h<E> >= 2 };' file
入力例:
NGNAEAREAX EAHVSELYCI FNWGNLACQM AWKLRMDHIT PRYMFNYMVM
NCNREDEEEQ EAHVSELYCI FNWGNLACQM AWKLRMDHIT PRYMFNYMVM
出力例:
NGNAEAREAX EAHVSELYCI FNWGNLACQM AWKLRMDHIT PRYMFNYMVM
RakuはPerlファミリーのプログラミング言語です。公開された質問は、Rakuが完璧なキー/値の問題であるようです(注:解決策に正規表現はありません)。
つまり、lines
読み取ると、各行はスペースで区切られ、words
最初の単語が削除されます。[0]
最初の単語はcomb
個々の文字で編集されます。
この時点から、各文字はハッシュ(以前に宣言されていた)に入力され、%h
すぐにその文字(トピック変数として表示されます$_
)はハッシュ内で唯一の文字になり、値はこの回数によって決まりますkey
(プラスプラス)。key
%h{$_}++
%h
この時点でコードからハッシュを返すと、say %h.sort
次のようになります。
(A => 3 E => 2 G => 1 N => 2 R => 1 X => 1)
(C => 1 D => 1 E => 4 N => 2 Q => 1 R => 1)
トップレベルのコードソリューションの最後の説明では、各文字をキーとしてハッシュし、ハッシュされた%h
""キーの値を 。見つかった場合は、行全体(省略形、ここでは入力行を表します)が返されます。contains
"R" & "E" & "G" & "X"
E
>= 2
.put
$_.put
$_
https://docs.raku.org/言語/hashmap
https://perlgeek.de/blog-en/perl-5-to-6/08-junctions.html
https://raku.org
答え3
これには予測演算子を使用できます。
grep -P '^\s*+(?=\S*R)(?=\S*E\S*E)(?=\S*G)(?=\S*X)'
ここで見つける:
^
行の先頭で一致\s*+
すべての先行スペース(ある場合)をスキップして振り返らないでください。(?=\S*R)
この場所にR
空白以外の文字が次の数だけあるかどうかを事前に確認してください。(?=\S*E\S*E)
同じ場所でE
空白以外の部分を見てくださいE
。- あなたは理解しました。
答え4
awk
以下は、単語の文字数を数え、その関数を使用して最初にクエリ単語(「REGEX」)を処理し、次に入力された最初のフィールドの各単語を処理する関数です。次に、最初のフィールド単語の文字数がクエリ単語を生成するのに十分であることを確認し、そうであればその単語を印刷します。
awk -v word="REGEX" '
function calc(w,a) {
for (i = 1; i <= length(w); ++i) a[substr(w,i,1)]++
}
BEGIN {
# Character frequencies of the query word are stored in q.
calc(word,q)
}
{
# Get character frequencies for $1 and see if any
# frequency in q are higher. If so, next.
delete f; calc($1,f)
for (ch in q) if (f[ch] < q[ch]) next
print $1
}' file
質問の入力に対して実行すると、出力が提供されますNGNAEAREAX
。
ここで唯一の非効率性は、興味のない文字の頻度を計算することです。