Bash测试:“ =〜”是做什么的?


Answers:


46

~实际上是操作者的一部分=~,其执行将字符串其左侧到其右边的扩展正则表达式的正则表达式匹配。

[[ "string" =~ pattern ]]

请注意,字符串应加引号,而正则表达式不应加引号。

Perl编程语言中使用了类似的运算符。

所理解的正则表达式bash与GNU grep带有-E标志所理解的正则表达式相同,即正则表达式的扩展集。


有点题外话,但要知道:

当与包含捕获组的正则表达式匹配时,每个组捕获的字符串部分在BASH_REMATCH数组中可用。在该阵列对应第零/第一个条目&中的替换模式sed的替换命令(或$&在Perl),这是与该模式匹配的串的位,而在索引1中的条目和起对应于\1\2等。在一个sed替换模式(或者$1$2等在Perl),即由每个括号匹配的位。

例:

string=$( date +%T )

if [[ "$string" =~ ^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]]; then
  printf 'Got %s, %s and %s\n' \
    "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi

这可能输出

Got 09, 19 and 14

如果当前时间恰好是09:19:14。

数组名称的REMATCHBASH_REMATCH来自“正则表达式匹配”,即“ RE-Match”。


在非bashBourne类shell中,也可以使用expr有限的正则表达式匹配(仅使用基本正则表达式)。

一个小例子:

$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123

2
它与grep -E仅在GNU系统上以及仅在使用未引用的变量作为模式时才了解的内容相同[[ $var = $pattern ]](请参阅[[ 'a b' =~ a\sb ]]vs p='a\sb'; [[ 'a b' =~ $p ]])。还请注意,shell引号会影响RE运算符的含义,并且shell标记化中需要引用一些字符,这可能会影响RE处理。[[ '\' =~ [\/] ]]返回false。ksh93还有更糟糕的问题。请参阅zsh(或bash 3.1)以获取更明智的方法,其中将shell引用和RE引用明确分开。的[的内置zshyash也有=~运营商。
斯特凡Chazelas

2
很酷off-topic!+1(
JJoao

@StéphaneChazelas它是如何“理智的”,无论本场比赛中的zsh ?:的[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]。还是那个引用*也匹配?[[ "This is a fine mess." =~ "T.........fin*es*" ]]
sorontar

(IMO)比较简单,因为它的规则要简单得多。外壳报价和RE转义显然是分开的。在[[ a =~ .* ]][[ a =~ '.*' ]]或中[[ a =~ \.\* ]],相同的.*RE传递给=~运算符。OTH中的bash[[ '\' =~ [)] ]]返回错误,是否尝试不[[ '\' =~ [\)] ]]匹配是否会知道?怎么样[[ '\' =~ [\/] ]](它在ksh93中执行)。怎么样c='a-z'; [[ a =~ ["$c"] ]](与=运营商比较)?另请参见:[[ '\' =~ [^]"."] ]]返回错误......请注意,你可以做shopt -s compat31bash拿到zsh行为。
斯特凡Chazelas

zsh/ bash -o compat31的行为[[ a =~ '.*' ]]也与[ a '=~' '.*' ](对于[支持的实现=~)或一致expr a : '.*'。OTOH,它与[[ a = '*' ]]vs 不一致[[ a = * ]](但是,glob是shell语言的一部分,而RE则不是)。
斯特凡Chazelas

4

您应该阅读本[[ expression ]]节下的bash手册页。

An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).

长话短说,=~是运算符,就像==和一样!=。它与右侧字符串中的实际正则表达式无关。


您能找出一些示例来说明=~在现实生活中的用法吗?
乔治·瓦西里乌

1
@GeorgeVasiliou我经常在将命令的输出放入变量的脚本中使用它。然后检查变量以查看其是否与某些字符串模式匹配。例如,如果您要根据该命令的某些错误输出采取某些措施,则此功能很有用。
Michael Martinez

@Sokel对于某些人来说,“ RTFM”说起来容易做起来难。⋯ man [[ expresssion ]]man [[什么也不返回。 help [[由于[[内部bash命令而返回有用的信息,但是没有说明是=~使用基本的还是扩展的正则表达式语法。you您引用的文本来自bash手册页。我意识到您说过“阅读bash手册页”,但起初,我以为您的意思是阅读bash中的手册页。无论如何,都man bash将返回一个巨大的文件,该文件长4139行(72页)。可以通过按进行搜索/▒▒▒,该键接受一个正则表达式,=~未指定其味道(例如)。
Alex Quinn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.