これは文法的に間違っています:
#!/usr/bin/env bash
dimension="4x5"
if [[ "$dimension" !=~ '[0-9]x[0-9]' ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
return 1;
fi
上記は構文が悪いです...だから私の質問は - これを行う方法はありますか?!=~
...だと思います!~
。もしそれが本当なら、否定ルールなんてそんなものでしょう。わかりました、テストしてみましたが、!~
これも機能しません。
答え1
!=~
キーワードにはor!~
演算子はありません[[
。代わりに、比較の結果を否定します。
[[ ! "string" =~ regex ]]
議論の引用に関してregex
、マニュアルには次のように記載されています。
パターンの任意の部分を引用符で囲むと、引用符で囲んだ部分が文字列として一致するように強制できます。
regex
したがって、シェル オプションcompat31
が設定されていない限り、正規表現部分は引用符で囲まないでください。
shopt
...compat31
[[
設定されている場合、bashは条件付きコマンドの=~
演算子に対する引用符付き引数に関してバージョン3.1の動作に変更します。
与えられた例については、以下を試してください:
if [[ ! "$dimension" =~ ^[0123456789]+x[0123456789]+$ ]]; then
printf '%s %s\n' "'$dimension'" 'is not a valid dimension.'
fi
regex
は でアンカーする必要があります^...$
。そうでない場合は、foo1x1fubar
有効なディメンションと見なされます。
また、入力検証などには範囲を使用しないように注意してください0-9
。特に、セキュリティに敏感なコンテキストでのサニタイズの場合は、多くのロケールで、これらの範囲には、従来よりも多くの文字 (または複数の文字で構成される照合要素) が含まれるためです (C/POSIX ロケールでは現在も含まれています)。
の場合=~
、bash
はglobasciiranges
ここでは役に立ちません。Ubuntu 19.10 のロケールでは、の有無にかかわらず、は0123456789 に加えて 1040 種類の文字に一致することen_GB.UTF-8
がわかりました。少なくとも私の場合、それらはすべて 0 から 8 までの 10 進数字と何らかの関係がありますが、それは一般には保証されていません。bash
[0-9]
globasciiranges
一方、[[:digit:]]
および は[0123456789]
、POSIX 準拠のシステムでは 10 および のみに一致します。
sh
次のように、標準の構文とワイルドカード パターンを使用してこれを行うこともできます。
valid_geometry() case $1 in
(*[!x0123456789]* | *x | x* | *x*x*) false;;
(*x*) true;;
(*) false;;
esac
if ! valid_geometry "$dimension"; then
...
fi
または、ksh glob を使用する場合 (がなくても および でもbash -O extglob
サポートされます)、次のようにしますbash
。[[
extglob
if [[ $dimension != +([0123456789])x+([0123456789]) ]]; then
...
fi
答え2
さて、これはうまくいくようです:
if [[ ! "$dimension" =~ [0-9]+x[0-9]+ ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
しかし、なぜ一重引用符で囲むと機能しないのか疑問に思います。
if [[ ! "$dimension" =~ '[0-9]+x[0-9]+' ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
これが私の解決策です:
dimension="3x5"
regex='[0-9]+x[0-9]+'
if [[ ! "$dimension" =~ $regex ]]; then
echo 'wtf meng, the dimension needs an "x" in it.'
exit 1;
fi
[0-9]+
これで、正規表現を引用するために一重引用符を使用できるようになりましたが、[[ ]] 内から $regex を参照するときには二重引用符を避ける必要があります。ただし、 ..の省略形があるかどうかはまだわかりません。