実行後
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
されたソート要素など)と一致します。d
e
指定済み置く。
仕様には以下を含めることができます。
- (or)のような範囲は、および間に配置された要素を
a-z
照合するために使用されます[.dzs.]-z
(通常はabcdefghijklmnoprstuvwxyzを含むが、ほとんどのロケールでははるかに多くを含みます)。さらに、POSIXはPOSIXロケール以外のロケールを指定しないため、これらの範囲が組み合わせ順序に基づいている程度は実装ごとに大きく異なります。a
z
- 単一文字または対照要素(
x
、、[.dsz.]
) - POSIX文字クラス
[:alpha:]
、[:digit:]
[=e=]
基本照合順序の重みが等しいすべての照合順序要素と同じ等価クラスe
(次のような項目を含めることができますé
)
たとえば、[acd[=e=]h-k[:digit:][.dzs.]]
組み合わせ要素の一致が、またはのように、またはのa
間c
に組み合わせられている場合、分類は次のようになります。d
dzs
e
h
k
数字。
仕様がで始まる場合は、^
照合要素と一致しますが、セットを補完します。これは、指定された要素ではなく、すべての照合順序要素です。
したがって、は、および間に配置されていない[^a-z]
すべての組み合わせ要素と一致します。たとえば、ロケールや実装によっては、一致しない場合と一致する可能性がありますが、一致する場合も一致しない場合があります。a
z
1
ẑ
X
DSZ
grep
a
x
z
é
だから、grep '[^a-z]\{22\}'
一致する行含む照合順序の前または後に続く一連22
の組み合わせ要素です。a
z
Whileは、22個の組み合わせ要素のシーケンスを含む行grep -v '[a-z]\{22\}'
と一致します。a
z
同じ要素を一致させることはほとんど不可能です。 2つの要素の間に配置された要素が21個以下の行を-v
一致させる必要があります。ただし、ロケールが複数文字の組み合わせ要素をサポートしている場合、実際には不可能です。たとえば、ハンガリーのロケールではonと一致しますが、それも一致するので、そこにあります。 will match on しかし、また一致します。[a-z]
[^a-z]
[a-z]
dsz
d
s
z
[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文字未満であるためです。)