Bash

使用 bash [[ 命令的 =~ 運算符進行正則表達式匹配的問題

  • October 17, 2017

在 OSX 上,我正在建構一個函式來驗證日期格式,然後將它們轉換為紀元時間。如果沒有錯誤,該函式應驗證日期是否為以下格式之一: 01/01/1970 10:00PM10: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) 的兩側添加了一個額外的空格,以便我們可以匹配datetimedate time中的任何一個(兩個組件之間必須有空格)。正如所寫,日期部分要求 2000 年代的四位數年份;隨意放寬這個要求。

我曾經' '指定一個空間。如果您願意,可以用它[[:space:]]來表示任何空格。

進行比較後,您可以選擇日期部分為${BASH_REMATCH[1]},時間部分為${BASH_REMATCH[2]}

引用自:https://unix.stackexchange.com/questions/398148