是=和=〜相当于检查简单的正则表达式?

时间:2016-06-20 10:04:32

标签: regex bash

阅读comment by Charles Duffy我遇到了一个问题:使用==~检查简单正则表达式有什么不同吗?

当我们只想检查一个字符串是否是另一个字符串的一部分时,这些选项是等价的:

$ [[ hello = *el* ]] && echo "yes"
yes
$ [[ hello =~ el ]] && echo "yes"
yes

如果将正则表达式存储在变量中,也会发生相同的情况:

$ re="[0-9]"
$ number=2
$ [[ $number = $re ]] && echo "yes"
yes
$ [[ $number = *$re* ]] && echo "yes"
yes

但是,检查非文字字符串不适用于=,需要使用=~

$ date=20160620
$ [[ $date = [0-9]{4}(0[0-9]|1[0-2])([0-2][0-9]|3[0-1]) ]] && echo "yes"
bash: syntax error in conditional expression: unexpected token `('
bash: syntax error near `[0-9]{4}(0'
$ [[ $date =~ [0-9]{4}(0[0-9]|1[0-2])([0-2][0-9]|3[0-1]) ]] && echo "yes"
yes
$ [[ $date =~ ^[0-9]{4}(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])$ ]] && echo "yes"
yes

在一般性能和POSIX方面应该使用什么?

请注意,所有这些都是基于我的GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)

1 个答案:

答案 0 :(得分:2)

使用BASH中的===仅支持全局模式匹配。

您的前两个示例产生的结果相同,因为您在第一个匹配*el*(glob),在第二个示例中匹配el(在glob或regex或plain字符串中相同)。

但是当你使用正确的正则表达式使用字符类,量词,锚等时,你必须只使用=~来匹配正则表达式。

这正是第二个块中语法错误的原因,因为shell试图将给定的正则表达式解释为glob模式。

来自Bash Reference Manual → 3.2.4.2 Conditional Constructs

[[ expression ]]
     

当使用'=='和'!='运算符时,右边的字符串   运算符被认为是一种模式并根据其匹配   下面Pattern Matching中描述的规则,就好像extglob   shell选项已启用。 '='运算符与'=='相同。

     

另一个二元运算符'=〜'可用,具有相同的   优先级为'=='和'!='。使用时,右边的字符串   运算符被认为是扩展的正则表达式   相应地匹配(如在regex3中))。