Shell 內建模式匹配(Glob/Pattern Matching)
用於 case、[[ ... ]]、參數擴展 ${var#pattern}、檔名展開等,非正則表達式,語法更簡單:
| 模式 | 含義 |
* | 匹配任意長度字串(含空) |
? | 匹配任意單字符 |
[abc] | 匹配集合內任一字符 |
[a-z] | 匹配範圍內任一字符 |
[^abc] | 匹配非集合字符 |
[[:alnum:]] | POSIX 字符類(alnum/alpha/digit/space 等) |
*(pattern) | 擴展模式:零次或多次(需 shopt -s extglob) |
+(pattern) | 一次或多次 |
?(pattern) | 零次或一次 |
@(p1|p2) | 匹配 p1 或 p2 |
!(pattern) | 不匹配 pattern |
Bash 正則表達式([[ string =~ regex ]])
使用 ERE(擴展正則),BASH_REMATCH 數組捕獲分組:
if [[ 'user123' =~ ^([a-z]+)([0-9]+)$ ]]; then
echo "前綴: ${BASH_REMATCH[1]}" # user
echo "數字: ${BASH_REMATCH[2]}" # 123
fi
外部工具正則(grep/sed/awk)
| 工具 | 預設語法 | 擴展正則 | Perl 正則 |
| grep | BRE | -E | -P |
| sed | BRE | -E / -r | 不支援 |
| awk | ERE | 原生 | 不支援 |
常用正則構建塊(ERE/PCRE 通用)
| 需求 | 模式 |
| IPv4 地址 | ((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]?) |
| Email 簡易 | [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} |
| URL (HTTP/HTTPS) | https?://[^\s/$.?#].[^\s]* |
| 日期 YYYY-MM-DD | \d{4}-\d{2}-\d{2} (PCRE) / [0-9]{4}-[0-9]{2}-[0-9]{2} (ERE) |
| 手機號 (中國大陸) | 1[3-9]\d{9} |
| 身份證號 (18 位) | [1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx] |
實戰技巧
- 變數引用正則:
regex="^$prefix.*$suffix$",[[ $str =~ $regex ]](變數不加引號)。
- 調試正則:
echo 'test' | grep -E --color 'pattern' 或 regex101.com 線上測試。
- 避免貪婪陷阱:
.*? (PCRE 非貪婪),ERE 用精確字符類替代 .*。
- 效能:固定前綴
^prefix 可大幅加速;長字串用 grep -F 避免正則引擎。
總結
Shell 三層模式體系:Glob(檔名/參數展開) → Bash [[ =~ ]] (ERE) → 外部工具。根據場景選擇最輕量的層級:簡單前綴/後綴用 Glob;結構化提取用 [[ =~ ]];流式文本處理用 grep -E/sed -E/awk;複雜驗證用 grep -P 或編程語言。