本质上,我正在测试一个变量,以确保其内容与特定的时间格式匹配:4位数字,上午/下午/上午/下午,没有空格(即下午1204点)。我有这么多工作要做:
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
请帮忙,谢谢。
使用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] ]]
这使用了扩展的globs。请注意,不需要shopt -s extglob
在[[ ... ]]
中使用扩展的globs:在Condition Constructs一节中,对于关于[[ ... ]]
的文档,您可以阅读:
当使用
==
和!=
运算符时,运算符右侧的字符串被视为一个模式,并根据下面在模式匹配中描述的规则进行匹配,就像启用了extglob
shell选项一样。
要在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。
bash模式不是正则表达式。它们也不是Java模式,我认为这正是您想要使用的(尽管还不清楚)。
您可以(也应该)阅读bash手册中关于模式匹配的章节,这是一个完整的模式特性列表。在那里,你会看到:
-
[...]
匹配作为所附字符类描述中的字符之一的单个字符 -
*
匹配任意数量的字符
因此, 我想你正在寻找的是: [01][0-9][0-5][0-9][aApP][mM] 尽管这有点慷慨,因为它将匹配,例如,下午1300点("这是四月的一个寒冷的日子,时钟敲了十三下。")[0-2###apAP]*
匹配字符0、1、2、#、a