文字列にASCIIスペース文字が含まれているかどうかをテストする方法は?

文字列にASCIIスペース文字が含まれているかどうかをテストする方法は?

文字列に空白文字があるかどうかを確認するには? Unicode 幅が 0 の文字など、ASCII 以外の項目について心配する必要はありません。文字列がシェル変数(たとえば)に格納されていると想定できます$string

動作例:

abc空白があるのでtrueを返します。

\tabcタブがあるのでtrueを返します。

abc空白文字がないため、falseを返す必要があります。

abc
hello

改行文字があるのでtrueを返す必要があります。


一般的なコマンドラインユーティリティ(sed、、、、)を使用するソリューションで十分ですgrepawkbash

答え1

POSIX sh構文から:

case $string in
  (*[[:blank:]]*) echo "string contains at least one character classified as blank";;
  (*[[:space:]]*) echo "string contains at least one character classified as whitespace (but not blank)";;
  (*) echo no character classified as whitespace;;
esac

[:blank:]のサブセットでなければなりません[:space:][:blank:]少なくともスペースとTABと、少なくともスペース、[:space:]TAB、NL、CR、FF、およびVTを含めることが保証されます。

これは、使用されるエンコードとロケールの文字分類に基づいています。ほとんどのシステムでは、すべてのロケールはASCII文字セットまたはASCII親セットを使用します(一部の日本語ロケールの一部のBSDにあるMS-Kanjiを無視すると、0x5cが代わりに使用されます¥(文字\がありません\!)。残りはASCII親セットです。 )。

$stringEBCDICベースのシステムでも、1つ以上のASCIIエンコーディングを含むASCIIスペースを確認するには、バイト値セットを指定するか、iconvテーマを現在の文字セットからASCIIに変換する必要があります。

ascii_whitespace=$(printf ' \r\n\r\f\v' | iconv -t ASCII)
# or
ascii_whitespace=$(printf '\40\11\12\13\14\15')
case $string in
  (["$ascii_whitespace"]) echo contains at least one ASCII whitespace;;
esac

\15このシステムでは改行文字が発生しないことを願っています。)

答え2

文字列がシェル変数に格納されているとします$string。この場合、bashシェルとして指定したので、[[ ... ]]テスト構成で組み込み正規表現マッチングを使用できます。

if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi

シェルスクリプトでも使用できます。

いくつかの使用例:

~$ string=" hello "
~$ if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi
Contains whitespace

~$ string=$'\thello'
~$ if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi
Contains whitespace

~$ string="hello"
~$ if [[ "$string" =~ [[:space:]] ]]; then echo "Contains whitespace"; else echo "Doesn't contain whitespace"; fi
Doesn't contain whitespace

メモ:これはPOSIX文字クラスを使用します[:space:]。たとえば、参照してください。

[:space:]との間の微妙さのために[:blank:]。空白を作るキャラクターだけを考慮したい場合同じ行の中(たとえば、<space>および\t)に切り替える必要があります[:blank:](ただし、一部のロケールでは[:blank:]垂直スペース文字も含まれます)。

答え3

使用幸せ(以前のPerl6)

~$ echo "abc " | raku -ne '.contains(/ \s /).say'
True
~$ echo "abc" | raku -ne '.contains(/ \s /).say'
False

-ne上記のRakuコードは、awkに似たコマンドラインフラグを使用して入力を1行ずつ実行します。 Rakuのcontainsメソッドはブール値を返します。先行.点は、containsコマンドラインから入力を取得したことを示します。または(または)標準入力

~$ echo "abc " | raku -ne 'say .contains(/ \s /) ?? True !! False;'
    True
~$ echo "abc" | raku -ne 'say .contains(/ \s /) ?? True !! False;'
    False

??上記は、Rakuの三項演算子であるTest True Falseを使用しているため、もう少し複雑です!!。 Rakuは論理的Trueで論理的なFalseので、上記の戻り値を引用する必要はありません。ここでの利点は、TrueandFalseを希望の二重引用符に簡単に変更できることです(例:"Yes"and)"No"

おそらくOPの質問には以下が含まれます。水平空白に関しては、Raku は\h水平スペースと\v垂直スペースを区別できます。

~$ raku -e 'put "abc\t";' | raku -ne 'say .contains(/ \h /);'
True
~$ raku -e 'put "abc\t";' | raku -ne 'say .contains(/ \v /);'
False

OPは、複数行の入力文字列を処理する必要があるかどうかを明らかにしませんでした。スペースの場合は常に「正の数」ですが、水平スペースの場合は「負の数」にすることができます。 [数値列を入力と考えてください]。とにかくRakuでは、上記のように1行ずつ入力を読み取ることができ(デフォルトでは自動的に行われます)、\n名前は奇妙ですが記憶に残る読み取り入力を一度に使用できます(eol改行を保持)slurp

1行ずつ読みます(autochomps):

~$ raku -e 'put "1\n2\n3";' | raku -ne 'say .contains(/ \h /);'
False
False
False
~$ raku -e 'put "1\n2\n3";' | raku -e 'for lines() {say .contains(/ \h /)};'
False
False
False

一度にすべての内容を読む(自動咀嚼なし):

~$ raku -e 'put "1\n2\n3";' | raku -e 'say slurp.contains(/ \v /);'
True
~$ raku -e 'put "1\n2\n3";' | raku -e 'put slurp.contains(/ \h /);'
False

付録:OPの声明に頼っています。「ASCII以外のものについては心配する必要はありません…」〜のように「Unicodeが処理されても構いません」。もしただASCIIスペースは処理されます(他のすべてのスペースは拒否されます)。これはRakuが管理できますが、上記では扱っていません。 RakuはすでにUnicodeをサポートしているため、\s(略語<space>)と\h(略語<blank>)の\v両方がデフォルトでUnicodeを受け入れます。

非ASCII(水平)スペースを拒否するには、次のカスタム文字クラスを試すことができます<:ASCII> & <blank>

例:

~$ raku -e 'put "\xA0";' | raku -ne 'put .contains(/ <blank> / );'
True
~$ raku -e 'put "\xA0";' | raku -ne 'put .contains(/ <:ASCII> & <blank> / );'
False

https://docs.raku.org/言語/operators#index-entry-operator_ternary
https://docs.raku.org/言語/regexes#\h_and_\H
https://docs.raku.org/routine/contains
https://raku.org

関連情報