從正則表達式開始:用模式匹配處理文字實戰指南

身為前端開發者,你一定常常遇到這樣的場景:使用者填完表單,你要檢查 Email 格不格式對、手機號碼是不是 11 位數;或是後端丟給你一坨雜亂的日誌,你只想把裡面的訂單編號、IP 位址全部抓出來。這些「從文字裡找規律、做驗證、做擷取」的工作,如果靠一堆 if-else 去硬刻,不但程式碼又臭又長,還很容易出 bug。這時候,你需要的就是正則表達式(Regular Expression,簡稱 Regex)

正則表達式本質上就是「用一串特殊符號寫成的搜尋規則」,幾乎所有程式語言(JavaScript、Python、Java、Go…)都支援。今天這篇「從正則表達式開始」實戰指南,我會帶你從語法一路打到真實專案裡的表單驗證與資料擷取。

一、正則表達式到底是什麼?

簡單說,正則表達式是一個「模式(Pattern)」。你告訴引擎:「我要找的是『開頭是字母、中間可以有一些數字、結尾是 @xxx.com』這種字串」,引擎就會照這個模式去文字裡比對。在 JavaScript 裡,它長這樣:

const pattern = /abc/;                 // 最簡單的寫法:配對包含 abc 的字串
const alsoPattern = new RegExp('abc'); // 用建構子動態建立

二、核心語法速覽(步驟 1)

先記住幾個最常用的「元字元」,它們是 Regex 的字母:

  • . 配對任意單一字元(除了換行)
  • \d 配對數字(0-9),\w 配對字母數字底線,\s 配對空白
  • ^ 代表「開頭」、$ 代表「結尾」
  • * 出現 0 次以上、+ 1 次以上、{n,m} n 到 m 次
  • [abc] 配對括號內任一個字元,[^0-9] 則是「非數字」
  • ( ) 用來「捕捉」群組,方便後續取出

三、實戰:表單驗證(步驟 2)

在前端表單裡,Regex 最常拿來做即時驗證。來看兩個真實例子:

// 驗證 Email(實務上建議再搭配後端驗證)
const emailRe = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRe.test('user@example.com')); // true

// 驗證中國手機號(1 開頭,第二碼 3-9,共 11 位)
const phoneRe = /^1[3-9]\d{9}$/;
console.log(phoneRe.test('13800000000')); // true

重點:前端驗證只是「使用者體驗」層級的擋箭牌,千萬不能當作安全防線。任何來自使用者的資料,後端一定要再驗證一次,否則很容易被繞過。

四、實戰:資料擷取(步驟 3)

除了驗證,Regex 更強的是「從一大段文字裡把想要的東西抓出來」。用 matchmatchAll

const log = '訂單 ORDER-1001 來自 192.168.1.1;訂單 ORDER-1002 來自 10.0.0.5';
const re = /ORDER-(\d+)\s+來自\s+(\d+\.\d+\.\d+\.\d+)/g;
for (const m of log.matchAll(re)) {
  console.log('訂單號:', m[1], 'IP:', m[2]);
}
// 訂單號: 1001 IP: 192.168.1.1
// 訂單號: 1002 IP: 10.0.0.5

這裡用括號 ( ) 把「訂單號」和「IP」分別捕捉成群組,m[1]m[2] 就能直接拿到,完全不用手刻字串切割。

五、效能與陷阱(步驟 4)

特別注意:正則表達式如果用錯,會有嚴重的效能與安全問題:

  • 災難性回溯(Catastrophic Backtracking):(a+)+$ 這種嵌套量詞,遇到超長又不匹配的輸入時,引擎會組合爆炸、直接卡死瀏覽器。處理使用者輸入時務必避免。
  • 不要拿 Regex 解析 HTML/JSON:結構化資料請用專門的解析器(DOMParser、JSON.parse),Regex 只適合「半結構化」或純文字。
  • 加上註解與分段:複雜規則用 /x 修飾符(或拆成多個小規則)提升可讀性,日後維護才不會看不懂自己寫了什麼。

互動話題:你在使用正則表達式時,踩過最慘的坑是什麼?是忘記轉義特殊字元,還是遇到過災難性回溯?歡迎在留言區分享你的「Regex 血淚史」!