正規表達式(Regular Expression)以及在Vim當中的用法
正規表達式(Regular Expression,以下簡稱regexp)最主要用於比對文字,例如搜尋
和取代
時,有時我們的搜尋規則較為複雜,無法使用一般搜尋功能。
範例一:刪除姓氏
例如這邊有一份文件,是一個賓客名單,我們將所有名字列在上面。現在因為隱私的關係,需要把所有姓氏移除。但大家名字都不相同,要如何移除呢?
1. Jason Sanfer
2. Jenniffer Rounder
3. Richtor Jose
4. Sam Johnson
...
一行一行移除絕非好方法,用一般搜尋取代也無法找出較為符合的規則。這時使用regexp的話會非常簡單,我們只需要考慮兩個邏輯。
- 所有姓氏都是一個英文單字
- 所有姓氏都在整行的結尾
依此規則只需要在搜尋欄位輸入:
/\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
以下簡單說明用法。
- %代表搜尋整個檔案
- s代表開始進行取代功能(substitute)
- 第一個斜線是分隔線,後方是搜尋目標
- 第二個斜線是分隔線,後方是取代內容
- 第三個斜線是代表結束取代內容的輸入
- g代表每個找到的目標都取代
依照上方的模式,我們可以輸入:
:%s/\v\w+$ //g
\v\w+$
是我們的搜尋目標,因此填入兩個分隔線中間。另外,我們是要刪除所有姓氏,所以在取代內容的部份就輸入空白,直接用兩個分隔線帶過。
這樣我們就在Vim中完成一個非常直覺的regexp搜尋取代啦!依照這個方式我們同樣也可以進行其他的regexp搜尋功能。
教學資源
- Derek Banas的YouTube教學三部曲:我個人很推這三部影片,很初級,只要在Vim當中跟著他操作一遍,大概就知道可以用在哪些地方了。
- Vim Regular Expressions
- 「三色傑克」的部落格文章:以上兩篇比較屬於瀏覽性質,大概看過去即可。如果有實際運用情況需要查詢,Google還是你最好的夥伴。
- Regex101:所有練習都可以在這個互動式的編輯介面實作,旁邊還會有用法說明。
- Tuts+:這是我最推的教學資源,不過是付費的,Jeffery Way這個人雖然長相和講話聲音搭不太起來,但他說話非常清楚,內容也很有條理,我很愛。之前是看他的[Sublime Text 2](https://code.tutsplus.com/courses/perfect-workflow-in-su互動式的編輯介面實作,旁邊還會有用法說明。