Linux中仅[[ ... ]]支持正则匹配,使用=~操作符(如[[ $str =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]),右侧为ERE语法;POSIX兼容场景可用grep -qE替代。

Linux 系统中,标准的 if [ ... ] 或 test 命令不支持正则表达式匹配。它们只支持文件测试、字符串相等(=、==)、模式通配(如 [[ string = pat* ]] 中的 glob 通配),但不是正则表达式(regex)。
真正能在条件判断中直接使用正则表达式的,是 [[ ... ]] 复合命令中的 =~ 操作符——这是 Bash(4.0+)和某些其他现代 shell(如 zsh)提供的扩展功能,专为正则匹配设计。
H3 使用 [[ string =~ pattern ]] 进行正则判断
[[ 是 Bash 的关键字,=~ 是其内置的正则匹配操作符,右侧 pattern 是扩展正则表达式(ERE)语法,无需转义 +、?、|、() 等。
str="2026-09-25"
if [[ $str =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
echo "是合法日期格式"
else
echo "格式不对"
fi⚠️ 注意:
[[和]]之间必须有空格;=~右侧的 pattern 不要加引号(否则会被当字面量,失去正则含义);- 若 pattern 含空格或变量,建议先赋值给变量再引用,避免解析错误;
- 匹配成功时返回状态码
0(即if成立),失败为1。
H3 常见正则匹配场景与写法
-
判断是否为纯数字
if [[ $var =~ ^[0-9]+$ ]]; then echo "是整数" fi
-
判断是否含邮箱特征(简单版)
if [[ $input =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then echo "看起来像邮箱" fi -
提取并验证 IP 地址片段
ip="192.168.1.100" if [[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] && \ [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; then echo "是有效 IPv4 地址" fi✅ 第一个
=~快速筛格式,第二个做数值范围校验(注意:Bash 不支持在正则中写25[0-5]这类逻辑的完整校验,实际建议用awk或函数辅助)
H3 替代方案:用 grep + $? 实现兼容性更强的判断
如果脚本需兼容 POSIX shell(如 /bin/sh)或旧版 Bash(< 3.2),不能用 [[ =~ ]],可用:
if echo "$str" | grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'; then
echo "匹配成功"
fi-
-q静默输出,只看退出状态; -
-E启用扩展正则(等价于egrep); - 兼容所有支持
grep -E的系统,包括最小化 Linux 容器环境。
H3 注意事项与避坑点
-
[[ string =~ (a|b) ]]中的括号()和竖线|是 ERE 特性,无需反斜杠; - 如果 pattern 存在变量插值,推荐写成:
pattern='^[a-z]+@example\.com$' if [[ $email =~ $pattern ]]; then ...
(此时
$pattern是未加引号的变量,Bash 会按 ERE 解析) -
^和$锚定的是整行,不是子串;若想匹配子串,去掉两端锚点,例如[[ $line =~ error|fail ]]; - 不支持捕获组反向引用(如
\1)或命名组,仅做“是否匹配”判断;需要提取内容请用BASH_REMATCH数组或grep -oP。
例如提取版本号:
ver="app-v2.3.1"
if [[ $ver =~ v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
echo "检测到版本: ${BASH_REMATCH[1]}" # 输出 2.3.1
fi
BASH_REMATCH是 Bash 内置数组,[0]是全匹配,[1]起是各捕获组内容。
不复杂但容易忽略。


















