【问题标题】:Are = and =~ equivalent to check simple regular expressions?= 和 =~ 是否等同于检查简单的正则表达式?
【发布时间】:2016-06-20 18:27:52
【问题描述】:

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

【问题讨论】:

  • 这就是 globbing 和 Regex 之间的区别。 = 使用通配符,而 =~ 使用正则表达式。
  • 如果您有选择,请选择正则表达式以提高效率;它通常更快。见stackoverflow.com/q/18412294/1566221。但正则表达式不是 posix。

标签: regex bash


【解决方案1】:

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

您的前 2 个示例产生了相同的结果,因为您在第一个示例中匹配 *el*(glob)和在第二个示例中匹配 el(在 glob 或正则表达式或纯字符串中相同)。

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

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


来自Bash Reference Manual → 3.2.4.2 Conditional Constructs:

[[ expression ]]

当使用‘==’和‘!=’操作符时,右边的字符串 运算符被认为是一个模式并根据 下面在Pattern Matching 中描述的规则,就像extglob 外壳选项已启用。 “=”运算符与“==”相同。

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

【讨论】:

  • 哦,太好了!从Bash reference manual - 3.2.4.2 Conditional Constructs,=~ (...) 使用时,运算符右侧的字符串被认为是扩展正则表达式并进行相应匹配,而当'=使用 =' 和 '!=' 运算符,运算符右侧的字符串被视为模式,并根据以下模式匹配中描述的规则进行匹配,就好像启用了 extglob shell 选项。非常感谢!
  • 没错,=、!= 和 == 也支持扩展 glob 模式
  • 好的,现在很清楚了。如果您不介意,我会在您的答案中添加参考资料,因此可以接受。谢谢!
  • 是的,请随时将它们添加到答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多