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';

這確保 SQLdatabase完整單詞,而不是 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 單詞」,而不會匹配到 MySQLnosql 這種包含 SQL 但不是獨立單詞的情況。

2️⃣ \\bdatabase\\b 只匹配完整的 database

SELECT * 
FROM articles 
WHERE content REGEXP '\\bdatabase\\b';

匹配

  • "這是一個關於 database 的文章"
  • "我正在研究 database"

不匹配

  • "databases 是很重要的技術"
  • "bigdatabase 這個字詞"

因為 \\bdatabase\\b 只會匹配 “database” 本身,不會匹配 "databases""bigdatabase"

\\bLIKE 的區別

有時候我們會使用 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 查詢技能!🔥

Similar Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *