これは構文上正しくありません。
#!/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
上記の構文はひどいです...だから私の質問は - それを行う方法はありますか?!=~
...そうだと思いますか!~
?これが真であれば、否定規則lulzについてはこれだけです。はい、テストしてみましたがうまく!~
いきませんでした...
答え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およびen_GB.UTF-8
ロケールでは0123456789に加えてbash
。少なくとも私の場合、すべて0から8までの10進数とは何の関係もありますが、通常これは保証されません。[0-9]
globasciiranges
一方、これらは10個のみ[[:digit:]]
一致し、[0123456789]
すべてのPOSIX互換システムで動作する必要があります。
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
これで一重引用符を使用して正規表現を引用できますが、[[]]内で$ regexを引用するときは二重引用符を使用しないでください。しかし、[0-9]+
頭字語があるかどうかはまだ疑問に思います。