必须用双中括号[[ ]],因其原生支持=~且语法容错性高;单中括号[ ]不支持=~会报错;正则不加双引号(可单引号),空格位置严格,支持分组、交替等复杂结构。

双中括号 [[ ]] 是 Bash 中处理复杂正则匹配最可靠的方式,它原生支持 =~ 操作符,且语法容错性远高于单中括号 [ ]。关键在于:必须用 [[ ]],不能用 [ ];正则表达式不加引号(或仅用单引号),变量可加双引号;空格位置严格。
必须用双中括号,单中括号不支持 =~
单中括号 [ ] 是 test 命令的别名,根本不识别 =~ 运算符。一旦写成:
if [ "$str" =~ ^[a-z]+\.[0-9]+$ ]; then ...
就会报错:syntax error: unexpected "(" 或类似解析失败。因为 [ 把 =~ 当作普通字符串或无效操作符处理。
正确写法是:
- 用
[[ ]]替代[ ] - 保持
[[和]]两侧有空格 -
=~两侧也必须各有一个空格(共五个空格:[[ $var =~ pattern ]])
正则表达式不加双引号,但可加单引号
双引号会禁用正则特性,把整个模式当字面量匹配。例如:
[[ "abc123" =~ "^[a-z]{3}[0-9]{3}$" ]] → 实际匹配的是字符串 "^[a-z]{3}[0-9]{3}$",不是正则逻辑。
推荐写法是不加引号,或只用单引号包裹正则:
-
[[ $str =~ ^[a-z]+\.com$ ]](推荐,简洁清晰) -
[[ $str =~ '^[a-z]+\.(org|com|net)$' ]](单引号可安全包含管道符、括号等) - 避免:
[[ $str =~ "^([a-z]+)\.com$" ]](双引号导致失效)
支持复杂正则结构,无需额外转义
[[ ]] 内部对正则引擎调用更直接,括号、量词、分组、字符类都可原样使用:
- 分组与捕获:
[[ "user@domain.com" =~ ^([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$ ]] - 交替匹配:
[[ $ext =~ ^(txt|log|conf)$ ]] - 边界与锚点:
[[ $line =~ ^\s*#.*$ ]] && echo "注释行" - 注意:反斜杠在 shell 层需保留(如
\.表示字面点),不需要像在grep里那样双重转义
结合逻辑运算符写多条件判断
双中括号天然支持 &&、||,避免嵌套或拆分判断:
- 同时满足多个正则:
if [[ $url =~ ^https?:// ]] && [[ $url =~ \.github\.com$ ]]; then ... - 排除特定模式:
if [[ $file != *.tmp ]] && [[ $file =~ ^[a-zA-Z][a-zA-Z0-9_]*\.sh$ ]]; then ... - 非匹配写法:
if ! [[ $input =~ ^[0-9]{3}-[0-9]{2}-[0-9]{4}$ ]]; then echo "格式错误"; fi











