如何使用測試否定正規表示式

如何使用測試否定正規表示式

這在語法上是錯誤的:

#!/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 選項:

shoptcompat31

如果設置,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]+..的簡寫

相關內容