2017-03-03 89 views
0

我試圖在case語句中匹配5到7個數字的字符串。沒有我試過成功的作品。 這是我嘗試過的一件事。如何匹配bash case語句中的數字字符串

^[0-9]*$) 
    echo "Got it!" 
    ;; 

我該如何成功做到這一點?

+0

這是正則表達式語法,但case語句採用全局樣式模式語法。 –

回答

4
$ shopt -s extglob 
$ isNum() { case $1 in (+([0-9])) echo 'Got it!' ;; esac; } 
$ isNum 123A 
$ isNum A123 
$ isNum 1234 
Got it! 

如果你還需要檢查的長度,這可能是分開進行:

isNum() { 
    local len=${#1} 
    if ((len < 5 || len > 7)); then return; fi 
    case $1 in (+([0-9])) echo 'Got it!' ;; esac 
} 

這裏的技巧是「extglob」(擴展水珠)語法,這使得類似的適當的正則表達式的功能。 extglob中的「+(...)」表示「1或更多...」。

有關詳細信息,請參見bash-hackers頁面。

除了ksh93,globs的功能不足以匹配特定的重複次數 - 您需要自己寫出來。例如:

# this is very clumsy, but works in all POSIX shells 
isNum() { 
    case $1 in [0-9][0-9][0-9][0-9][0-9])   : "Matched 5" ;; 
      [0-9][0-9][0-9][0-9][0-9][0-9])  : "Matched 6" ;; 
      [0-9][0-9][0-9][0-9][0-9][0-9][0-9]) : "Matched 7" ;; 
      *) return ;; 
    esac 
    echo "Got it!" # only reached if the "return" didn't happen 
} 

因此,你可能會更好過使用由馬克·裏德的回答中描述的慶典,只有正則表達式語法 - 又見the relevant bash-hackers page

+1

如果你不需要知道*究竟有多少個字符匹配,你應該使用較短(但仍很笨拙)的'[0-9] [0-9] [0-9] [0-9] [0 -9]?([0-9]?([0-9]))' – chepner

3

bash case語句中的模式是文件globs,而不是正則表達式。你最好的選擇可能是一個的if/else鏈,而不是case

if [[ "$string" =~ ^[0-9]{5,7}$ ]]; then 
    echo "Got it!" 
fi 

但是,如果你是對的確切長度不挑剔的話,你可以使用擴展的glob功能來匹配「1個或多個數字」:

shopt -s extglob 
case "$string" in 
    (+([0-9])) echo "Got it!";; 
esac 
0

如果你真的想用一個case聲明,那麼這將這樣的伎倆:

string=12345 
case "${#string}-${string}" in 
    5-[0-9]*) 
    echo "'${string}' contains 5 digits" 
    ;; 
    7-[0-9]*) 
    echo "'${string}' contains 7 digits" 
    ;; 
    *) 
    echo "Something else" 
    ;; 
esac 

的想法是計數的人物和預先考慮計數到數字,以便case字符串除了文本本身之外還包含有關長度的元數據。

+1

但是這也會匹配'1abcd'。例如,需要一個擴展的glob來工作:'5 - +([0-9])'。 –

+0

這可以被修改,以提供昂貴的POSIX兼容解決方案。將' - $(echo「$ string」| tr -d'[^ 0-9]')'添加到您正在檢查的字符串中,然後將' - 「$ string」'添加到每個模式。這將檢查字符串本身沒有被刪除非數字字符的行爲所修改。 – chepner