试图在bash条件语句/大小写中使用通配符并与精确的alpha字符混合,但失败了



本质上,我正在测试一个变量,以确保其内容与特定的时间格式匹配: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手册中关于模式匹配的章节,这是一个完整的模式特性列表。在那里,你会看到:

  • [...]匹配作为所附字符类描述中的字符之一的单个字符

  • *匹配任意数量的字符

因此,[0-2###apAP]*匹配字符012#a

我想你正在寻找的是:

[01][0-9][0-5][0-9][aApP][mM]

尽管这有点慷慨,因为它将匹配,例如,下午1300点("这是四月的一个寒冷的日子,时钟敲了十三下。")

最新更新