
正規表現に関する簡単な(簡単な)質問があります。順序に関係なく、すべてのトークンセットに一致する正規表現を考えたいと思います。
たとえば、米国の州名を含むファイルがあります。
Abbreviation:State name:Capital:Became a state
AL:Alabama:Montgomery:December 14, 1819
AK:Alaska:Juneau:January 3, 1959
AZ:Arizona:Phoenix:February 14, 1912
...
WI:Wisconsin:Madison:May 29, 1848
WY:Wyoming:Cheyenne:July 10, 1890
名前に「A」、「R」、「N」という文字があるすべての州(大文字と小文字を区別しない)を探したいとしましょう。
私は一つ作ることができます
$ cut -d: -f2 states.txt | tail -n +2 | grep -i a | grep -i r | grep -i n
もちろん、そのようなことが起こりました。
Arizona
Arkansas
California
Maryland
Nebraska
New Hampshire
North Carolina
North Dakota
Rhode Island
South Carolina
Virginia
West Virginia
3つの文字がすべて任意の順序で表示される場合は、単一の正規表現を使用して一致させる方法はありますか?
答え1
以下を使用する必要がありますawk
。
$ awk '/a|A/ && /R|r/ && /N|n/' file
Arizona
Arkansas
California
Maryland
Nebraska
New Hampshire
North Carolina
North Dakota
Rhode Island
South Carolina
Virginia
West Virginia
渡すとgawk
使えます大文字と小文字を無視:
gawk '/a/ && /r/ && /n/' IGNORECASE=1 file
答え2
このコマンドgrep
には適切なAND演算子がないため、この問題を解決するには創造性を発揮する必要があります。複数を選択してgrep
一緒に接続するときにこれを行うことができます。しかし、次のようにすることもできます。
$ echo -e "arie\narin" | grep -i '[arn].*[arn].*[arn]'
arin
これは、a、r、またはnの組み合わせを含むすべての文字列と一致し、このセットに3回現れる文字を含める必要があります。
空白の単語
スペースを処理するには、上記の正規表現を次のように調整できます。
$ echo -e "arie\narin\nar nie" | \
grep -i '[arn][[:alpha:]]*[arn][[:alpha:]]*[arn]'
arin
ここでは、ブロック間ですべてのタイプの文字を受け入れるのではなく、オプションでセットからのみ[arn]
文字[[:alpha:]]
を取得します。また、途中でゼロ個以上の文字がgrep
必要であることもお知らせします。*
答え3
cut -d: -f2 states.txt | tail -n +2 | egrep -i '[arn].*[arn].*[arn]'
答え4
まあ、1つのオプションは、sed
これがgrep
代替策よりはるかに遅くなる可能性があるということです。
cut -d: -f2 states.txt | tail -n +2 | sed -n -e '/a/I{/r/I{/n/Ip}}'
Arizona
Arkansas
California
Maryland
Nebraska
New Hampshire
North Carolina
North Dakota
Rhode Island
South Carolina
Virginia
West Virginia