変数に特別な制御文字(改行、バックスペース、またはキャリッジリターンなど)なしで有効なUTF-8文字列が含まれているかどうかをbashで確認する方法は?
答え1
ロケールが文字エンコーディングとしてUTF-8を使用しているとします(次を確認してくださいlocale charmap
。
[[ $string =~ ^[^[:cntrl:]]*$ ]]
動作する必要があります。ただし、少なくともGNUシステムでは、コードポイントが0x110000を超える文字を含むUTF-8エンコーディング文字列を拒否することはできません。UTF-8エンコーディングの現在の定義では無効になりました。)。これはbash
、パターンマッチングに使用されるシステムの正規表現ライブラリによって異なります。
GNUも同様ですexpr
:
expr " $string" : ' [^[:cntrl:]]*$' > /dev/null
zsh
ここからUTF-8ロケールの場所に切り替えることができます。
set -o extendedglob
[[ $string = [' '-$'\ud7fff'$'\ue000'-$'\U10FFFF']# && $string != *[[:cntrl:]]* ]]
システムに関係なく、一貫して動作する必要があります(少なくとも有効な文字一致の場合、文字がとして分類されるシステム間の違いを見つけることができます[:cntrl:]
)。
zsh globモードでは、マルチバイト文字ロケールの文字範囲は、UTF-8で常にUnicodeコードポイントである文字のワイド文字値に基づいています。有効な文字の一部を形成しないバイトには、文字ではなく0xD800..0xDFFF UTF16サロゲートペアの2番目の部分にある0xDC80..0xDCFF範囲のwchar_t値が割り当てられます(任意のバイトシーケンスを処理できるUnicode認識汎用メソッド)。
Bash glob パターンの文字範囲処理はほとんどランダムです。そのため、ここでは使用できません。
処理方法を検討することもできます。非文字、個人用キャラクター、システムが使用するUnicodeバージョンに現在割り当てられていない文字。コンセプトコントロールUnicodeの場合、文字もかなりあいまいです。 U+202E RIGHT-TO-LEFT OVERRIDE 文字、U+FEFF BOM 文字、商標数値例えばコントロール数字?