$ grep '[^az]\{22\}' /usr/share/dict/words 出力なし

$ grep '[^az]\{22\}' /usr/share/dict/words 出力なし

実行後

grep '[a-z]\{22\}' /usr/share/dict/words

出力は次のとおりです

counterrevolutionaries
electroencephalographs

しかし、実行するとき

grep '[^a-z]\{22\}' /usr/share/dict/words

出力がありません。

私はそれが次のようなものを生産すると予想しました。

grep -v '[a-z]\{22\}' /usr/share/dict/words

私の質問は何が間違っているのですか?

答え1

[specification]ソート要素(ロケールソートアルゴリズムで定義されている文字または文字シーケンス(たとえば、GNUシステムのハンガリーロケールの間に配置dzsされたソート要素など)と一致します。de指定済み置く。

仕様には以下を含めることができます。

  • (or)のような範囲は、および間に配置された要素をa-z照合するために使用されます[.dzs.]-z(通常はabcdefghijklmnoprstuvwxyzを含むが、ほとんどのロケールでははるかに多くを含みます)。さらに、POSIXはPOSIXロケール以外のロケールを指定しないため、これらの範囲が組み合わせ順序に基づいている程度は実装ごとに大きく異なります。az
  • 単一文字または対照要素(x、、[.dsz.]
  • POSIX文字クラス[:alpha:][:digit:]
  • [=e=]基本照合順序の重みが等しいすべての照合順序要素と同じ等価クラスe(次のような項目を含めることができます é

たとえば、[acd[=e=]h-k[:digit:][.dzs.]]組み合わせ要素の一致が、またはのように、またはのacに組み合わせられている場合、分類は次のようになります。ddzsehk数字

仕様がで始まる場合は、^照合要素と一致しますが、セットを補完します。これは、指定された要素ではなく、すべての照合順序要素です。

したがって、は、および間に配置されていない[^a-z]すべての組み合わせ要素と一致します。たとえば、ロケールや実装によっては、一致しない場合と一致する可能性がありますが、一致する場合も一致しない場合があります。az1XDSZgrepaxzé

だから、grep '[^a-z]\{22\}'一致する行含む照合順序の前または後に続く一連22の組み合わせ要素です。az

Whileは、22個の組み合わせ要素のシーケンスを含む行grep -v '[a-z]\{22\}'と一致します。az

同じ要素を一致させることはほとんど不可能です。 2つの要素の間に配置された要素が21個以下の行を-v一致させる必要があります。ただし、ロケールが複数文字の組み合わせ要素をサポートしている場合、実際には不可能です。たとえば、ハンガリーのロケールではonと一致しますが、それも一致するので、そこにあります。 will match on しかし、また一致します。[a-z][^a-z][a-z]dszdsz[a-z]{0,21}dszxxxyyyxxxyyyxxxyyyx[a-z]{22}

複数文字の組み合わせ要素を持たないロケールでは、次のことができます。

grep  '^[^a-z]*\([a-z]\{1,21\}[^a-z]\{1,\}\)*[a-z]\{0,21\}$'

grepいくつかのオプションで高度な正規構文をサポートする実装もあります。否定的なオペレーター。

たとえば、GNUまたはast-open実装は、オプションのperlのような正規表現をサポートしますgrep(GNU grepのlibpcre、ast-open独自のast-open grep実装)。-P(?!pattern) 負の予測演算子

(?!pattern)パターンがそこで一致しない場合、ターゲット文字列の任意の点で幅がゼロの一致が行われます。したがって、次のものを使用できます。

 grep -P '^(?!.*[a-z]{22})'

後ろに文字数がなく、22[a-z]秒がない場合は、行の先頭に一致します。ただし、PCRE(ast-openではない)では、[a-z]ロケールに関係なくabcdefghijklmnopqrstuvwxyzのみが一致します。

ast-openには-X彼らが言うオプションもあります拡張正規表現。これらの拡張正規表現には、!物事を否定する演算子があります。 (空の文字列を含む)を除くすべての項目x!と一致します。x

したがって、ast-openを使用すると、grep次のこともできます。

grep -X '^(.*[a-z]{22}.*)!$'

答え2

  • grep '[^a-z]\{22\}' /usr/share/dict/words

    /usr/share/dict/words小文字ではなく22文字の文字列を含むファイルの行を見つけます。ファイルにはそのような行が含まれていない可能性があります。 (このファイルに22個の文字以外の文字列が含まれているのはなぜですか?)

  • grep -v '[a-z]\{22\}' /usr/share/dict/words

    22文字の文字列を含まない行を見つけます。そのような行がたくさんあるかもしれません。 (ほとんどの単語が22文字未満であるためです。)

関連情報