尝试在 bash 条件 statement/case 中使用通配符与精确的 alpha 字符混合并失败
Trying to use wildcards in bash conditional statement/case mixed with exact alpha char and failing
本质上,我正在测试一个变量以确保它的内容匹配特定的时间格式:4 位数字,am/pm/AM/PM,没有空格(即 1204pm)。我已经完成了这么多工作:
tm0=1204pm; [[ $tm0 == [0-2###aApP]* ]] && echo PASS
或
tm0=1203pm; case $tm0 in [0-2###apAP]*) echo PASS; esac
但是当我尝试将最后一个字符指定为 "m" 时(最初我尝试指定 [Mm] 但那也不起作用)它失败了。
tm0=1204pm; [[ $tm0 == [0-2###aApP]m ]] && echo PASS
任何帮助,谢谢。
bash 模式不是正则表达式。它们也不是 Java 模式,我认为这就是您要使用的模式(尽管一点也不清楚)。
您可以(并且应该)阅读 bash manual chapter on pattern matching,这是模式特征的完整列表。在那里,你会看到:
[...]
匹配单个字符,该字符是封闭字符 class 描述
中的字符之一
*
匹配任意数量的任意字符
所以[0-2###apAP]*
匹配其中一个字符0,1,2, #, a,p, A,或 P,后跟任意数量的字符(包括 0)。
我想你要找的是:
[01][0-9][0-5][0-9][aApP][mM]
虽然这有点大方,因为它会匹配,例如 1300pm ("It was a bright cold day in April, and the clocks were striking thirteen.")
使用 globs:
[[ $tm0 == [01][0-9][0-5][0-9][aApP][mM] ]]
请注意,这将验证,例如 1900pm
。如果你不想这样:
[[ $tm0 == @(0[0-9]|1[0-2])[0-5][0-9][aApP][mM] ]]
这使用 extended globs. Note that you don't need shopt -s extglob
to use extended globs inside [[ ... ]]
: in section Condition Constructs,有关 [[ ... ]]
的文档您可以阅读:
When the ==
and !=
operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if the extglob
shell option were enabled.
要在 case
语句中使用此功能,您需要启用 extglob
.
使用正则表达式:
[[ $tm0 =~ ^(0[0-9]|1[0-2])([0-5][0-9])([aApP][mM])$ ]]
通过这些分组,您可以在 BASH_REMATCH[0]
中得到小时,在 BASH_REMATCH[1]
中得到分钟,在 BASH_REMATCH[2]
中得到 am/pm。
本质上,我正在测试一个变量以确保它的内容匹配特定的时间格式:4 位数字,am/pm/AM/PM,没有空格(即 1204pm)。我已经完成了这么多工作:
tm0=1204pm; [[ $tm0 == [0-2###aApP]* ]] && echo PASS
或
tm0=1203pm; case $tm0 in [0-2###apAP]*) echo PASS; esac
但是当我尝试将最后一个字符指定为 "m" 时(最初我尝试指定 [Mm] 但那也不起作用)它失败了。
tm0=1204pm; [[ $tm0 == [0-2###aApP]m ]] && echo PASS
任何帮助,谢谢。
bash 模式不是正则表达式。它们也不是 Java 模式,我认为这就是您要使用的模式(尽管一点也不清楚)。
您可以(并且应该)阅读 bash manual chapter on pattern matching,这是模式特征的完整列表。在那里,你会看到:
[...]
匹配单个字符,该字符是封闭字符 class 描述 中的字符之一
*
匹配任意数量的任意字符
所以[0-2###apAP]*
匹配其中一个字符0,1,2, #, a,p, A,或 P,后跟任意数量的字符(包括 0)。
我想你要找的是:
[01][0-9][0-5][0-9][aApP][mM]
虽然这有点大方,因为它会匹配,例如 1300pm ("It was a bright cold day in April, and the clocks were striking thirteen.")
使用 globs:
[[ $tm0 == [01][0-9][0-5][0-9][aApP][mM] ]]
请注意,这将验证,例如 1900pm
。如果你不想这样:
[[ $tm0 == @(0[0-9]|1[0-2])[0-5][0-9][aApP][mM] ]]
这使用 extended globs. Note that you don't need shopt -s extglob
to use extended globs inside [[ ... ]]
: in section Condition Constructs,有关 [[ ... ]]
的文档您可以阅读:
When the
==
and!=
operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if theextglob
shell option were enabled.
要在 case
语句中使用此功能,您需要启用 extglob
.
使用正则表达式:
[[ $tm0 =~ ^(0[0-9]|1[0-2])([0-5][0-9])([aApP][mM])$ ]]
通过这些分组,您可以在 BASH_REMATCH[0]
中得到小时,在 BASH_REMATCH[1]
中得到分钟,在 BASH_REMATCH[2]
中得到 am/pm。