SQL 正規表示式(Regex)入門
更新日期: 2025 年 3 月 4 日
在處理資料時,我們常常需要根據特定模式來篩選數據。
例如,想要查找所有電子郵件地址、符合特定格式的電話號碼,或者尋找包含特定關鍵字的內容,這時候 SQL 的 正規表示式(Regular Expressions,簡稱 Regex) 就能派上用場。
雖然 SQL 本身提供了 LIKE
運算符來進行基本的字串匹配,但 Regex 提供了更強大的模式匹配能力,可以用來處理更複雜的篩選條件。
本篇文章將帶你了解 SQL 中如何使用正規表示式,以及不同 SQL 資料庫系統(如 MySQL、PostgreSQL)對 Regex 的支援。
SQL 正規表示式基礎
正規表示式(Regex)是一種用於字串匹配與操作的語法規則,允許我們使用特殊符號來描述特定的字串模式。例如:
^[A-Z]+$
→ 代表 全部都是大寫字母。\d{3}-\d{3}-\d{4}
→ 代表 符合 000-000-0000 格式的電話號碼。\bSQL\b
→ 代表 完整匹配 SQL 這個單詞。
在 SQL 中,正規表示式常用於:
- 篩選符合特定格式的數據(如 Email、電話號碼、身份證字號)
- 查找包含特定字串的數據(如文章標題、描述內容)
- 資料驗證(如密碼強度檢查)
SQL 正規表示式的語法
不同的 SQL 資料庫對 Regex 的支援方式不同,以下介紹 MySQL 和 PostgreSQL 的使用方式。
MySQL 中的 REGEXP
在 MySQL 中,REGEXP
運算符用來匹配正規表示式:
SELECT *
FROM users
WHERE email REGEXP '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
這條 SQL 語句會查找所有符合 Email 格式的使用者。
常見 Regex 符號(MySQL 支援)
符號 | 說明 | 範例 |
---|---|---|
. | 代表任意單一字元 | a.b 可匹配 acb、abb |
* | 代表零個或多個前一個字元 | ab* 可匹配 a、ab、abb |
+ | 代表至少一個前一個字元 | ab+ 可匹配 ab、abb,但不匹配 a |
? | 代表零個或一個前一個字元 | ab? 可匹配 a 或 ab |
^ | 代表字串開頭 | ^SQL 只匹配以 SQL 開頭的字串 |
$ | 代表字串結尾 | SQL$ 只匹配以 SQL 結尾的字串 |
[abc] | 代表匹配 a、b 或 c 任一字元 | h[aeiou]llo 可匹配 hello、hillo |
[^abc] | 代表不匹配 a、b 或 c | [^0-9] 代表不包含數字 |
{n} | 代表剛好匹配 n 次 | \d{3} 代表 匹配 3 位數字 |
示範:查找符合電話號碼格式的資料
SELECT *
FROM customers
WHERE phone REGEXP '^[0-9]{3}-[0-9]{3}-[0-9]{4}$';
這會篩選出 符合 123-456-7890
格式的電話號碼。
PostgreSQL 中的 ~ 運算符
PostgreSQL 支援更強大的正規表示式匹配,透過 ~
運算符來執行:
SELECT *
FROM users
WHERE email ~ '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
這與 MySQL 的 REGEXP
相似,但 PostgreSQL 提供 更多的 Regex 功能,如 SIMILAR TO
運算符,甚至支援 POSIX
規範的正規表示式。
PostgreSQL 特有的 Regex 運算符
運算符 | 說明 |
---|---|
~ | 代表正規表示式匹配 |
~* | 代表不區分大小寫的正規表示式匹配 |
!~ | 代表不匹配正規表示式 |
!~* | 代表不區分大小寫的非匹配 |
示範:查找不包含數字的使用者名稱
SELECT *
FROM users
WHERE username !~ '[0-9]';
這條 SQL 會排除所有包含數字的使用者名稱。
SQL Regex 的應用場景
Email 格式驗證
SELECT *
FROM users
WHERE email REGEXP '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
這可確保 Email 地址符合標準格式,如 [email protected]
。
查找特定開頭的數據
查找所有以 "admin_"
開頭的使用者:
SELECT *
FROM users
WHERE username REGEXP '^admin_';
過濾不安全的密碼
如果想找出**不夠安全(只包含數字或字母)**的密碼:
SELECT *
FROM users
WHERE password NOT REGEXP '^(?=.*[a-zA-Z])(?=.*[0-9]).{8,}$';
這確保密碼至少包含 8 個字元,且必須包含數字與字母。
查找包含特定字詞的內容
如果我們想查找某些文章提到了 “SQL” 或 “database”,可以這樣寫:
SELECT *
FROM articles
WHERE content REGEXP '\\b(SQL|database)\\b';
這確保 SQL
或 database
是完整單詞,而不是 nosql
這樣的字串。
補充:
\\b
在正規表示式中的意義
\b
在 正規表示式(Regex) 中代表 「單詞邊界(Word Boundary)」。它用來確保匹配的字串是完整的單詞,而不只是某個單詞的一部分。在 SQL 中,由於
\
是跳脫字元(escape character),所以我們在 SQL 查詢中通常需要使用\\b
(雙反斜線\\
),來代表正規表示式中的\b
。
\\b
如何運作?
\\b
會匹配單詞的邊界,也就是:
- 單詞的開頭(如果前面是空格、標點符號或字串的開頭)
- 單詞的結尾(如果後面是空格、標點符號或字串的結尾)
簡單來說,它確保查找的字詞是獨立的完整單詞,而不會匹配到單詞的一部分。
示範:單詞匹配
1️⃣
\\bSQL\\b
只匹配完整的SQL
SELECT * FROM articles WHERE content REGEXP '\\bSQL\\b';
✅ 匹配:
"SQL 是一種資料庫語言"
"我正在學習 SQL"
❌ 不匹配:
"MySQL 是一種資料庫"
"nosql 也是一種技術"
因為
\\bSQL\\b
只會匹配「完整的 SQL 單詞」,而不會匹配到MySQL
或nosql
這種包含SQL
但不是獨立單詞的情況。2️⃣
\\bdatabase\\b
只匹配完整的database
SELECT * FROM articles WHERE content REGEXP '\\bdatabase\\b';
✅ 匹配:
"這是一個關於 database 的文章"
"我正在研究 database"
❌ 不匹配:
"databases 是很重要的技術"
"bigdatabase 這個字詞"
因為
\\bdatabase\\b
只會匹配 “database” 本身,不會匹配"databases"
或"bigdatabase"
。
\\b
與LIKE
的區別有時候我們會使用
LIKE
來搜尋關鍵字,但LIKE
無法區分單詞邊界。例如:SELECT * FROM articles WHERE content LIKE '%SQL%';
這會匹配到:
"SQL 是一種語言"
✅"MySQL 也是一種語言"
(可能不是我們想要的)但如果改用:
SELECT * FROM articles WHERE content REGEXP '\\bSQL\\b';
這樣就只會匹配完整的
SQL
,不會錯誤地匹配MySQL
。
結論
SQL 的正規表示式(Regex)提供了強大的模式匹配功能,讓我們能夠精準地篩選資料,適用於 Email 驗證、格式檢查、搜尋特定內容等場景。
- MySQL 使用
REGEXP
來匹配正規表示式。 - PostgreSQL 則使用
~
、!~
來處理 Regex,並提供更強大的功能。
掌握 SQL Regex,可以讓我們在資料查詢、驗證和過濾上變得更加高效!🚀
如果你想更深入了解,建議實際在資料庫中測試不同的 Regex 表達式,透過練習來加強你的 SQL 查詢技能!🔥