MySQL 內建 REGEXP 運算子支援正則表達式模式匹配,功能遠強於 LIKE。本文系統整理模式字元語法、實戰範例、效能考量與版本差異。
基本語法
SELECT * FROM table_name WHERE column_name REGEXP 'pattern';
-- 等同於
SELECT * FROM table_name WHERE column_name RLIKE 'pattern';
- 返回
1 (匹配) 或 0 (不匹配)
- 任一操作數為
NULL 時返回 NULL
- MySQL 8.0+ 採用 ICU 正則引擎,語法更標準、支援 Unicode 屬性
核心模式字元速查表
| 元字元 | 說明 | 範例 | 匹配範例 |
^ | 字串開頭 | '^A' | Apple, Alpha |
$ | 字串結尾 | 'ing$' | testing, running |
. | 任意單一字元 (含換行) | 'a.c' | abc, aXc, a-c |
[...] | 字元集合 (任一) | '[aeiou]' | a, e, i, o, u |
[^...] | 排除字元集合 | '[^0-9]' | 非數字字元 |
| | 或 (Alternation) | 'cat|dog' | cat, dog |
* | 前一元素 0 次或多次 | 'ab*c' | ac, abc, abbc, abbbc |
+ | 前一元素 1 次或多次 | 'ab+c' | abc, abbc (不匹配 ac) |
? | 前一元素 0 次或 1 次 | 'ab?c' | ac, abc |
{n} | 前一元素恰好 n 次 | 'a{3}' | aaa |
{m,n} | 前一元素 m 到 n 次 | 'ab{1,3}' | ab, abb, abbb |
(...) | 分組捕獲 | '(ab)+' | ab, abab, ababab |
\d | 數字 (相當 [0-9]) | '\d{4}' | 2024, 1234 |
\w | 單字字元 [a-zA-Z0-9_] | '\w+' | user_name, var1 |
實戰範例集
-- 1. 以 L 開頭
SELECT * FROM info WHERE name REGEXP '^L';
-- 2. 以 c 結尾
SELECT * FROM info WHERE name REGEXP 'c$';
-- 3. 以 L 開頭 y 結尾,中間任意兩字元
SELECT * FROM info WHERE name REGEXP '^L..y$';
-- 4. 包含 c、e、o 任一字母
SELECT * FROM info WHERE name REGEXP '[ceo]';
-- 5. 包含數字
SELECT * FROM info WHERE name REGEXP '[0-9]';
-- 或
SELECT * FROM info WHERE name REGEXP '\d';
-- 6. 包含數字或 a-c 字母
SELECT * FROM info WHERE name REGEXP '[0-9a-c]';
-- 7. 排除 a-w 字母與數字 (特殊符號、中文等)
SELECT * FROM info WHERE name REGEXP '[^a-w0-9]';
-- 8. 包含 ic、uc、ab 任一子串
SELECT * FROM info WHERE name REGEXP 'ic|uc|ab';
-- 9. c 前面有 0 個或多個 a
SELECT * FROM info WHERE name REGEXP 'a*c'; -- 匹配 c, ac, aac, aaac...
-- 10. c 前面有 1 個或多個 a
SELECT * FROM info WHERE name REGEXP 'a+c'; -- 匹配 ac, aac... (不匹配 c)
-- 11. 連續 3 個 a
SELECT * FROM info WHERE name REGEXP 'a{3}';
-- 12. ab 出現 1 到 3 次
SELECT * FROM info WHERE name REGEXP '(ab){1,3}';
MySQL 8.0+ 新特性 (ICU 引擎)
- 支援
\p{L} (Unicode 字母)、\p{N} (Unicode 數字) 等屬性類別
- 支援先行斷言
(?=...)、後行斷言 (?<=...) (8.0.4+)
- 大小寫敏感由字符集排序規則決定,可用
COLLATE 指定
REGEXP_REPLACE(), REGEXP_SUBSTR(), REGEXP_INSTR() 等新函數
效能優化建議
- 避免前導萬用字元:
'%abc%' (LIKE) 或 '.*abc' (REGEXP) 導致全表掃描
- 優先使用 LIKE 簡單前綴匹配:
'abc%' 可用索引,REGEXP '^abc' 8.0+ 亦可用索引
- 複雜正則考慮應用層處理:將候選集用簡單 SQL 過濾後,在應用程式用語言級正則 (PCRE/JS) 二次過濾
- 建立函數索引 (8.0+):
CREATE INDEX idx_name_regex ON t ((name REGEXP '^pattern$')); (視版本支援度)
LIKE vs REGEXP 快速選型
| 場景 | 推薦 | 理由 |
| 固定前綴/後綴 | LIKE | 可用索引、語法簡單、效能最佳 |
| 通配符中間位置 | LIKE | 全掃描同 REGEXP,但 LIKE 更易讀 |
| 字元類別/數量/分組/或邏輯 | REGEXP | LIKE 無法表達 |
| 資料清洗/驗證/抽取 | REGEXP / 應用層 | 複雜邏輯 SQL 難維護 |