毋庸多言,在vim中正規表達式得到了十分廣泛的應用。最常用的 / 和 :s 指令中,正規表達式都是不可或缺的。下面對vim中的正規表達式的一些難點進行說明。
關于magic
vim中有個magic的設定。設定方法為:
:set magic " 設定magic
:set nomagic " 取消magic
:h magic " 檢視幫助
vim畢竟是個編輯器,正規表達式中包含的大量元字元如果原封不動地引用(像perl那樣),勢必會給不懂正規表達式的人造成麻煩,比如 /foo(1) 指令,大多數人都用它來查找foo(1)這個字元串,但如果按照正規表達式來解釋,被查找的對象就成了 foo1 了。
于是,vim就規定,正規表達式的元字元必須用反斜杠進行轉義才行,如上面的例子,如果确實要用正規表達式,就應當寫成 /foo/(1/) 。但是,像 . * 這種極其常用的元字元,都加上反斜杠就太麻煩了。而且,衆口難調,有些人喜歡用正規表達式,有些人不喜歡用……
為了解決這個問題,vim設定了 magic 這個東西。簡單地說, magic就是設定哪些元字元要加反斜杠哪些不用加的。簡單來說:
- magic (/m):除了 $ . * ^ 之外其他元字元都要加反斜杠。
- nomagic (/M):除了 $ ^ 之外其他元字元都要加反斜杠。
這個設定也可以在正規表達式中通過 /m /M 開關臨時切換。 /m 後面的正規表達式會按照 magic 處理,/M 後面的正規表達式按照 nomagic 處理,而忽略實際的magic設定。
例如:
//m.* # 查找任意字元串
//M.* # 查找字元串 .* (點号後面跟個星号)
另外還有更強大的 /v 和 /V。
- /v (即 very magic 之意):任何元字元都不用加反斜杠
- /V (即 very nomagic 之意):任何元字元都必須加反斜杠
例如:
//v(a.c){3}$ # 查找行尾的abcaccadc
//m(a.c){3}$ # 查找行尾的(abc){3}
//M(a.c){3}$ # 查找行尾的(a.c){3}
//V(a.c){3}$ # 查找任意位置的(a.c){3}$
預設設定是 magic,vim也推薦大家都使用magic的設定,在有特殊需要時,直接通過 /v/m/M/V 即可。
本文下面使用的元字元都是 magic 模式下的。
量詞
vim的量詞與perl相比一點也不遜色。
vim | Perl | 意義 |
* | * | 0個或多個(比對優先) |
/+ | + | 1個或多個(比對優先) |
/? 或 /= | ? | 0個或1個(比對優先),/?不能在 ? 指令(逆向查找)中使用 |
/{n,m} | {n,m} | n個到m個(比對優先) |
/{n,} | {n,} | 最少n個(比對優先) |
/{,m} | {,m} | 最多m個(比對優先) |
/{n} | {n} | 恰好n個 |
/{-n,m} | {n,m}? | n個到m個(忽略優先) |
/{-} | *? | 0個或多個(忽略優先) |
/{-1,} | +? | 1個或多個(忽略優先) |
/{-,1} | ?? | 0個或1個(忽略優先) |
從上表中可見,vim的忽略優先量詞不像perl的 *? +? ?? 那樣,而是統一使用 /{- 實作的。這大概跟忽略優先量詞不常用有關吧。
環視和固化分組
vim居然還支援環視和固化分組的功能,強大,贊一個

關于環視的解釋請參考Yurii的《精通正規表達式》 一書吧。
vim | Perl | 意義 |
/@= | (?= | 順序環視 |
/@! | (?! | 順序否定環視 |
/@<= | (?<= | 逆序環視 |
/@<! | (?<! | 逆序否定環視 |
/@> | (?> | 固化分組 |
/%(atom/) | (?: | 非捕獲型括号 |
和perl稍有不同的是,vim中的環視和固化分組的模式的位置與perl不同。例如,查找緊跟在 foo 之後的 bar,perl将模式寫在環視的括号内,而vim将模式寫在環視的元字元之前。
# Perl的寫法
/(?<=foo)bar/
# vim的寫法
//(foo/)/@<=bar