正規表達式(Regular Expression)以及在Vim當中的用法


正規表達式(Regular Expression,以下簡稱regexp)最主要用於比對文字,例如搜尋取代時,有時我們的搜尋規則較為複雜,無法使用一般搜尋功能。

範例一:刪除姓氏

例如這邊有一份文件,是一個賓客名單,我們將所有名字列在上面。現在因為隱私的關係,需要把所有姓氏移除。但大家名字都不相同,要如何移除呢?

1. Jason Sanfer
2. Jenniffer Rounder
3. Richtor Jose
4. Sam Johnson
...

一行一行移除絕非好方法,用一般搜尋取代也無法找出較為符合的規則。這時使用regexp的話會非常簡單,我們只需要考慮兩個邏輯。

  1. 所有姓氏都是一個英文單字
  2. 所有姓氏都在整行的結尾

依此規則只需要在搜尋欄位輸入:

/\w+$ /g

就可以選取所有姓氏。

「蛤?這什麼鬼?」

簡單來說,前後兩個斜線/代表宣告我們要使用regexp,中間的\w可以選取任何單一英文字母,而後面的+則是選取一個任何長度的英文單字,尾端的$代表選取句子的結尾。而在整句的最後還有一個g代表global,也就是將所有情況都選起來,如果沒有設定g,搜尋只會將第一個遇到的情況選擇起來。整段拼湊起來意思就是「選取所有在結尾的一個英文單字」。

範例二:將tab替換為空白

撰寫程式時會使用tab鍵來縮排,但常因為排版的關係,使用兩個空白鍵是較為理想的狀況。假如我們在修改其他人的程式時,需要將檔案內所有的tab都改成兩個空白鍵,可以進行以下搜尋:

/\t/g

\t代表tab字元,這樣就可以將文件內所有tab選起,至於取代功能,各編輯器的方式不一,以下用Vim當做例子。

Vim當中的正規表達式

使用Vim作為文字編輯器,勢必要使用到不少regexp進行搜尋取代,每個文字編輯器都有內建的正規表達式使用方法,Vim相較於其他編輯器,有較為特殊的啟動方式。

進入Vim以後,在Normal Mode底下按/開始搜尋,這時若輸入文字,就是進行一般的搜尋。如果要使用regexp,必須先輸入\v代表進入"Very Magic"模式,當然...這是Vim裡面的術語,基本上就是我們平常用的regexp,只能說設計這個模式的人覺得正規表達式很神吧。

若要了解各項模式的差異,輸入:help magic可以了解各模式的差異,包括了No Magic模式和Magic模式,用法和regexp稍微有點差異,但都是用於不同搜尋情況的功能。本人跟Vim還沒那麼熟,這邊只說明最普遍的Very Magic模式。

以剛剛要刪除所有姓氏的情況來看,我們可以輸入:

/\v\w+$ 

第一個/是Vim的搜尋符號,後方的\v代表進入regexp搜尋模式,接著才是我們剛進行的\w+$搜尋。

這邊還要注意一點,就是在Vim當中不使用兩個斜線/來宣告使用regexp,而是使用\v切換模式來進行宣告,所以跟文章一開始使用的兩個例子稍有不同。

若要進行取代,先複習一下Vim的取代指令:

:%s/要搜尋目標/取代內容/g

以下簡單說明用法。

  1. %代表搜尋整個檔案
  2. s代表開始進行取代功能(substitute)
  3. 第一個斜線是分隔線,後方是搜尋目標
  4. 第二個斜線是分隔線,後方是取代內容
  5. 第三個斜線是代表結束取代內容的輸入
  6. g代表每個找到的目標都取代

依照上方的模式,我們可以輸入:

:%s/\v\w+$ //g

\v\w+$是我們的搜尋目標,因此填入兩個分隔線中間。另外,我們是要刪除所有姓氏,所以在取代內容的部份就輸入空白,直接用兩個分隔線帶過。

這樣我們就在Vim中完成一個非常直覺的regexp搜尋取代啦!依照這個方式我們同樣也可以進行其他的regexp搜尋功能。

教學資源

  1. Derek Banas的YouTube教學三部曲:我個人很推這三部影片,很初級,只要在Vim當中跟著他操作一遍,大概就知道可以用在哪些地方了。
  2. Vim Regular Expressions
  3. 「三色傑克」的部落格文章:以上兩篇比較屬於瀏覽性質,大概看過去即可。如果有實際運用情況需要查詢,Google還是你最好的夥伴。
  4. Regex101:所有練習都可以在這個互動式的編輯介面實作,旁邊還會有用法說明。
  5. Tuts+:這是我最推的教學資源,不過是付費的,Jeffery Way這個人雖然長相和講話聲音搭不太起來,但他說話非常清楚,內容也很有條理,我很愛。之前是看他的[Sublime Text 2](https://code.tutsplus.com/courses/perfect-workflow-in-su‹互動式的編輯介面實作,旁邊還會有用法說明。