bash 正则表达式中 '(' 的十六进制代码

CLB*_*CLB 2 shell bash regular-expression ascii hex

我在 shell 中有一个奇怪的行为。

当我尝试将正则表达式中的“_”与其十六进制代码匹配时,它可以工作,但不能与“(”。

$ regex1=$'\x5f'
$ pattern1='_'
$ if [[ $pattern1 =~ $regex1 ]]; then echo yes; else echo no; fi
yes

$ regex2=$'\x28'
$ pattern2='('
$ if [[ $pattern2 =~ $regex2 ]]; then echo yes; else echo no; fi
no
Run Code Online (Sandbox Code Playgroud)

你能解释一下这种行为吗?

ilk*_*chu 6

regex2=$'\x28'完全等同于regex2='(',shell$'...'在分配发生时处理引号。并且(其本身是一个无效的正则表达式,因此[[ =~ ]]通过返回退出状态来报告错误2

$ re='('; [[ "(" =~ $re ]]; echo "$?"
2
Run Code Online (Sandbox Code Playgroud)

(当然,在if语句中,您无法区分1“不匹配”的退出代码和2“错误”的退出代码之间的区别,但它就在那里。)

您需要从正则表达式中转义左括号:

$ re='\('; [[ "(" =~ $re ]] && echo match
match
Run Code Online (Sandbox Code Playgroud)

或将其放在括号组中:

$ re='[(]'; [[ "(" =~ $re ]] && echo match
match
Run Code Online (Sandbox Code Playgroud)

在快速测试中,Bash 的正则表达式不支持十六进制或八进制字符转义,因此re='\050're='\x28'不起作用。