阅读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)
。
答案 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中))。