web-dev-qa-db-ja.com

'[a-z] *'がアルファベット以外の文字列と一致するのはなぜですか?

次の2行を含むファイルalphanumがあります。

123 abc
this is a line

sed 's/[a-z]*/SUB/' alphanumを実行すると、次の出力が得られる理由について混乱しています。

SUB123 abc
SUB is a line

私は期待していました:

123 SUB
SUB is a line

修正を見つけました(代わりにsed 's/[a-z][a-z]*/SUB/'を使用してください)が、なぜ機能するのかわからず、私の機能しません。

手伝ってくれますか?

9
Fakher Mokadem

パターン[a-z]*は、aからzの範囲のzero以上の文字に一致します(actual文字は、現在のロケール)。文字列123 abcの先頭にそのような文字はありません(つまり、パターンが一致します)。また、this is a lineの先頭には4文字あります。

少なくともoneの一致が必要な場合は、[a-z][a-z]*または[a-z]\{1,\}を使用するか、sed -Eで拡張正規表現を有効にして[a-z]+を使用します。

パターンが一致する場所を視覚化するには、各一致の前後に括弧を追加します。

$ sed 's/[a-z]*/(&)/' file
()123 abc
(this) is a line

または、行のすべての一致を表示するには:

$ sed 's/[a-z]*/(&)/g' file
()1()2()3() (abc)
(this) (is) (a) (line)

最後の結果を

$ sed -E 's/[a-z]+/(&)/g' file
123 (abc)
(this) (is) (a) (line)
28
Kusalananda

*一致ゼロ以上前のアトムの繰り返し。すべての正規表現エンジンは最初の一致を見つけようとします。文字列の先頭にちょうどゼロ文字の部分文字列があるので、それが一致します。文字列が文字で始まる場合、*はできる限り多く一致しますが、これは左端の一致を見つけることに次ぐものです。

長さがゼロの一致は少し問題になる可能性があります。ご覧のように、解決策は、パターンを変更して少なくとも1つの文字が必要になるようにすることです。拡張正規表現を使用すると、+そのため:sed -E 's/[a-z]+/SUB/'

楽しみにしてみてください:

echo 'less than 123 words' | sed 's/[0-9]*/x/g'
12
ilkkachu