使用 bash [[ 命令的 =~ 运算符进行正则表达式匹配的问题

jes*_*e_b 5 osx bash date regular-expression

在 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
}
Run Code Online (Sandbox Code Playgroud)

它目前工作正常,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
Run Code Online (Sandbox Code Playgroud)

谢谢!

我还尝试了以下正则表达式:

(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)
Run Code Online (Sandbox Code Playgroud)

roa*_*ima 8

如果您可以访问 GNU,一种选择date是让其为您完成工作并完全避免 RE 复杂性:

checkTIME () {
    convert_time=$(date --date "$1" +'%s' 2>/dev/null)
    if [[ -z "$convert_time" ]]
    then
        echo 'ERROR!'
        exit 1
    fi
}
Run Code Online (Sandbox Code Playgroud)

由于您已建议您无权访问 GNUdate并且您需要 RE 进行匹配以进行验证,因此您可以使用此方法。(我知道你已经提供了其他几个。)

[[ " $1 " =~ ^' '*([01]?[0-9]/[0123]?[0-9]/2[0-9][0-9][0-9])?' '+([01]?[0-9]:[0-5][0-9][AP]M)?' '*$ ]]
Run Code Online (Sandbox Code Playgroud)

我在输入参数 ( $1) 的两侧添加了一个额外的空格,以便我们可以匹配datetimedate time中的任何一个(两个组件之间必须有空格)。正如所写的那样,日期部分要求 2000 年代的四位数年份;随意放宽这个要求。

我曾经' '指定一个空格。[[:space:]]如果您愿意,您可以用来表示任何空格。

进行比较后,您可以选择日期组件为${BASH_REMATCH[1]},时间组件为${BASH_REMATCH[2]}


Rob*_*rtL 7

\d匹配某些版本的正则表达式 (perl) 中的十进制数字,但在用于命令运算符的扩展正则表达式中不匹配。=~[[bash

因此,将\dto更改[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 扩展正则表达式语法 。