使用 bash [[ 命令的 =~ 運算符進行正則表達式匹配的問題
在 OSX 上,我正在建構一個函式來驗證日期格式,然後將它們轉換為紀元時間。如果沒有錯誤,該函式應驗證日期是否為以下格式之一:
01/01/1970 10:00PM
或10:00PM
(%m/%d/%Y %I:%M%p
或%I:%M%p
)功能
checkTIME () { local CONVERT_CHK_TIME="$1" if [[ "$CONVERT_CHK_TIME" =~ ^(0[0-9]|1[0-2]):[0-9][0-9](AM|PM)$ ]]; then CONVERT_TIME="$(date -j -f "%I:%M%p" "$CONVERT_CHK_TIME" "+%s")" elif [[ "$CONVERT_CHK_TIME" =~ (0[0-9]|1[0-2])\/([0-2][0-9]|3[0-1])\/\d{4}\s[0-9][0-9]:[0-9][0-9](AM|PM) ]]; then CONVERT_TIME="$(date -j -f "%m/%d/%Y %I:%M%p" "$CONVERT_CHK_TIME" "+%s")" else echo "ERROR!" exit 1 fi }
它目前可以正常工作,
10:00PM
但是當我嘗試時無法匹配01/10/2017 10:00PM
我這樣稱呼它:
./convert '01/10/2017 10:00PM' ... ... + [[ -n 01/10/2017 10:00PM ]] + checkTIME '01/10/2017 10:00PM' + local 'CONVERT_CHK_TIME=01/10/2017 10:00PM' + [[ 01/10/2017 10:00PM =~ ^(0[0-9]|1[0-2]):[0-9][0-9](AM|PM)$ ]] + [[ 01/10/2017 10:00PM =~ (0[0-9]|1[0-2])/([0-2][0-9]|3[0-1])/d{4}s[0-9][0-9]:[0-9][0-9](AM|PM) ]] + echo 'ERROR!' ERROR! + exit 1
謝謝!
我還嘗試了以下正則表達式:
(0[0-9]|1[0-2])\/([0-2][0-9]|3[0-1])\/\d{4}\ [0-9][0-9]:[0-9][0-9](AM|PM)
\d
匹配某些版本的正則表達式=~
( perl ) 中的十進制數字,但不匹配用於.[[``bash
因此,將 更改
\d
為[0-9]
匹配 4 個十進制數字的模式。同樣對於
\s
。要匹配一個文字空格字元,請將 替換為\s
轉義空格 (\
)。如果要匹配 1 個或多個空格(空格或製表符),則將 替換\s
為[[:blank:]]+
.更重要的是,為了避免這些正則表達式混淆:
man bash
表示=~
正則表達式根據擴展的正則表達式語法進行匹配,如regex(3)
.
man 3 regex
(POSIX 正則表達式函式)說SEE ALSO regex(7)
。
man 7 regex
給出了正則表達式語法的描述,並說SEE ALSO POSIX.2, section 2.8 (Regular Expression Notation)
.您可以在The Open Group 的Posix 正則表達式文件中找到完整的 POSIX 擴展正則表達式語法 。
如果您可以訪問 GNU,那麼一種選擇
date
是讓它為您工作並完全避免 RE 的複雜性:checkTIME () { convert_time=$(date --date "$1" +'%s' 2>/dev/null) if [[ -z "$convert_time" ]] then echo 'ERROR!' exit 1 fi }
由於您已告知您無權訪問 GNU
date
,並且您需要 RE 匹配以進行驗證,因此您可以使用這種方法。(我知道你已經提供了其他幾個。)[[ " $1 " =~ ^' '*([01]?[0-9]/[0123]?[0-9]/2[0-9][0-9][0-9])?' '+([01]?[0-9]:[0-5][0-9][AP]M)?' '*$ ]]
我在輸入參數 (
$1
) 的兩側添加了一個額外的空格,以便我們可以匹配date、time或date time中的任何一個(兩個組件之間必須有空格)。正如所寫,日期部分要求 2000 年代的四位數年份;隨意放寬這個要求。我曾經
' '
指定一個空間。如果您願意,可以用它[[:space:]]
來表示任何空格。進行比較後,您可以選擇日期部分為
${BASH_REMATCH[1]}
,時間部分為${BASH_REMATCH[2]}
。