這在語法上是錯誤的:
#!/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
設定了 shell 選項:
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 之外,還可以匹配 1040 個不同的字符,無論是否bash
帶有。至少在我的例子中,它們都與十進制數字 0 到 8 存在某種關係,但這通常不能保證。[0-9]
globasciiranges
另一方面,[[:digit:]]
和[0123456789]
只匹配這 10 個 且 應該在任何 POSIX 相容系統上。
您也可以使用標準sh
語法和通配符模式來完成此操作,例如:
valid_geometry() case $1 in
(*[!x0123456789]* | *x | x* | *x*x*) false;;
(*x*) true;;
(*) false;;
esac
if ! valid_geometry "$dimension"; then
...
fi
或使用 ksh globs (也受 和 的支持,甚至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]+
..的簡寫