什麼是正規表示法#

正規表示法(Regular Expression, regex)是一套用特殊符號描述字串模式的語法。它不是一個程式,而是一種被其他工具支援的語法標準。支援正規表示法的工具包括 grep、sed、awk、vim、Python、JavaScript 等。

正規表示法的價值在於:用簡短的模式描述,就能匹配大量符合規則的字串。這在搜尋 log、驗證輸入格式、批次文字處理等場景中不可或缺。

正規表示法 vs. 萬用字元#

初學者常混淆這兩者,但它們是完全不同的機制:

萬用字元(Globbing)正規表示法(Regex)
使用場景Shell 的檔案名稱匹配文字內容的模式匹配
* 的意義匹配任意字元(零或多個)前一個字元重複零或多次
處理者Shell 本身grep、sed、awk 等工具

這是最常見的混淆點。Shell 的 ls *.txt 中的 * 是萬用字元,由 Shell 展開為符合的檔名。而 grep 'a*' file 中的 * 是正規表示法,表示「前面的 a 重複零次或多次」。兩者語法相似但意義完全不同。

基礎正規表示法#

核心語法元素#

符號意義
.匹配任意一個字元
*前一個字元重複零次或多次
^行首定位
$行尾定位
[]字元集合,匹配其中任一個
[^]反向字元集合,不匹配其中任何一個
\{n\}前一個字元恰好重複 n 次
\{n,m\}前一個字元重複 n 到 m 次

語系對正規表示法的影響#

字元的排序方式取決於語系設定(LANG):

  • LANG=C:按 ASCII 碼排序(0-9A-Za-z
  • LANG=zh_TW.UTF-8:大小寫交錯排序(aAbBcC...

在使用 [a-z] 這類範圍表示時,語系設定會直接影響匹配結果。建議在 script 中使用字元類別(如 [:lower:][:upper:][:digit:])來避免語系差異帶來的問題。

sed:串流編輯器#

sed(Stream Editor)是一個非互動式的文字處理工具,以串流的方式逐行處理文字。它的設計哲學是:不需要開啟檔案、不需要互動操作,就能完成批次的文字替換與修改。

sed 的主要操作:

  • 刪除特定行
  • 替換匹配的文字
  • 新增/插入
  • 直接修改檔案內容(-i 選項)

sed 在 CI/CD pipeline 和自動化腳本中極為常用——批次修改設定檔、處理 log 輸出、過濾特定格式的資料。

延伸正規表示法#

基礎正規表示法中某些語法寫起來較繁瑣,延伸正規表示法(ERE)提供了更簡潔的寫法:

符號意義
+前一個字元重複一次或多次
?前一個字元出現零次或一次
|或(OR),匹配其中任一模式
()群組,將多個字元視為一個單元

grep 預設使用基礎正規表示法。要使用延伸正規表示法,需要用 grep -E(或 egrep)。

awk:欄位導向的資料處理#

awk 的核心思想是將每一行文字按分隔符號切割成多個欄位,然後針對欄位進行操作。它特別適合處理結構化的文字資料(如 /etc/passwd、CSV、log 檔)。

awk 的運作邏輯:

  1. 逐行讀取輸入
  2. 按分隔符號將每行切割成 $1$2$3…($0 是整行)
  3. 依條件判斷是否處理該行
  4. 執行指定的動作

grep、sed、awk 常被稱為 Linux 文字處理的「三劍客」:

  • grep 擅長搜尋——找出包含特定模式的行
  • sed 擅長替換——批次修改文字內容
  • awk 擅長分析——按欄位處理結構化資料

檔案比對工具#

  • diff:逐行比對兩個文字檔的差異,輸出可作為 patch 的輸入
  • cmp:逐 byte 比對,適合二進位檔案
  • patch:根據 diff 的輸出,將修改套用到檔案上

diff + patch 的組合是版本控制的原始形態。Git 的 diff 功能就是建立在類似的原理上。理解這個機制,有助於理解 Git 如何追蹤和管理程式碼變更。