Vim 的替換查找是其核心功能, 功能極其強大, 經過其規則匹配, 能夠很快速地完成咱們不少須要大量人力操做的工做, 並且可對多文件使用查找/替換功能.html
本系列教程共分爲如下五個部分:正則表達式
編程界實現了多種正則匹配引擎, vim 的正則匹配引擎是獨有的, 其風格相似於 POSIX
, 可是咱們可經過將其匹配模式設爲:編程
\v
: (very magic) 來開啓 Perl
模式, 此模式下(
已經被轉義, 若是要搜索 (
, 必須轉回原義, \(
\V
: (very nomagic) 來開啓開啓原義模式, 此模式下直接搜索(
便可搜索到 (
\m
: 默認模式, 不指定任何模式時使用的就是此模式. 此模式下僅部分字符有特殊含義, (
沒有被轉義, 仍然可經過 (
搜索到 (
\M
: (nomagic) 其功能相似於 \V
原義開關, 不一樣的是, 一些字符會自動具備特殊含義, 即符號 ^
與 $
本文只討論默認模式下(\m
模式)下的正則匹配, 其餘模式下的原理相似, 讀者可自行研究vim
元字符是正則匹配的一個概念, 經過元字符能夠快速找出目標字段.markdown
.
: 表示匹配任意 一個 字符. 例: c..l
表示任意以 c 開頭, 中間有兩個任意字符, l 結尾的字段..*
: 表示匹配 任意多個 字符. 例: c.*l
表示任意以 c 開頭 l 結尾的字段(不會將一個字段進行跨行處理, 所以很是智能, 很頻繁使用)$
: 匹配行尾. 例: /d.*$
表示匹配到以 d 開頭到行尾中的全部內容, /123$
表示以 123 結尾的全部字段^
: 匹配行首. 例: ^.*d
表示匹配到行首到 d 的全部內容, /^123
表示以 123 開頭的字段\<
: 匹配單詞詞首\>
: 匹配單詞詞尾. 例: /\<f\>
表示只匹配 f
單詞, 若是其前有任何字符它就不是單詞, 不會被匹配到.*
: 表示其前字符能夠重複 0~無數 次. 如 /be*
會匹配到 b
, be
, bee
..., 由於 e 重複零次就是沒有, 因此會返回 b, 貪婪匹配模式, greedy\+
: 表示其前字符必須重複 1~無數 次, 如 /be\+
會匹配到 be
, bee
, beee
..., 貪婪匹配模式\(-)
: 0 或多個, 非貪婪匹配模式, non-greedy, 與 *
相對\?
或 \=
: 表明其前字符必須重複 0 或者 1 次.\{n,m}
: 其前字符必須重複 n 到 m 次, 貪婪匹配模式\{-n,m}
: 其前字符必須重複 n 到 m 次, 非貪婪匹配模式[adz]
: 匹配 a
, d
, z
中的任意 一個, 括號內也但是數字, 如 [2-5]
表示匹配 2
, 3
, 4
, 5
中的任意一個數字\|
; 或的意思, 表示只要符合其前或其後任意一個字符便可. 例: /one\|two\|three
表示匹配 one, two, three 中的任意一個. end\(if\|while\|for\)
表示會查找到 endif, endwhile, endfor 中的任意一個.[^a]
: 匹配除 a
之外的任意 字符[a-c]
: 匹配 a
, b
, c
中的任意一個, 遞增的順序\d
: 匹配十進制數字中的任意一個, 等同於 [0-9]
. 例: /\d\d:\d\d:\d\d
表示查找如 17:31:00
格式的字符\D
: 匹配除十進制數字外的任意一個字符, 等同於 [^0-9]
\x
: 匹配十六進制數字中的任意一個, 等同於 [0-9A-Fa-f]
\X
: 匹配除十六進制數字外的任意一個字符, 等同於 [^0-9A-Fa-f]
\w
: 匹配一個單詞(對中文來講很是雞肋, 由於只有 Vim 斷定是單詞的纔會進行匹配, 與normal 模式下的 w
, b
, e
匹配規則相同)\W
: 匹配除單詞外的全部字符. 由於在 vim 中中文所有不被認爲是單詞, 所以, 此匹配會選中全部中文字段.\t
: 表明 tab , 可以使用此方法將全部 tab 替換爲空格\s
: 配空白字段, 包含 tab 與空格, 在 pattern 中使用此查找空白, 在 string 中就能夠直接使用空格或者 tab 來輸入以替換了\S
: 匹配非空白字段, 等同於 [^\s]
\n
: 匹配換行符\_s
: 匹配換行或空白\_a
: 匹配換行或單詞(由於是單詞, vim 不會匹配中文)\C
: 區分大小寫地查找或替換, 例: /\CText
表示只會查找Text
, 不會查找 text
或 tExt
等\c
: 不區分大小寫地查找替換(已經在 vim 中設置了默認不區分了)如上所述, .
, *
, [
, ]
, ^
, %
, /
, ?
, ~
, $
這十個字符有特殊含義, 若是對這十個字符進行匹配, 須要添加 \
編輯器
:noh
: 取消查找模式的高亮匹配*
: 全文查找當前光標處單詞 (n 爲向下方向)#
: 全文查找當前光標處單詞 (n 爲向上方向)n
: 下一個列出的關鍵字N
: 上一個列出的關鍵字gn
: 進入面向字符的可視模式, 並選中下一項匹配gN
: 進入面向字符的可視模式, 並選中上一項匹配gUgn
: 使下一處匹配改成大寫<C-r><C-w>
: 根據當前查找模式下已經輸入的內容結合全文進行自動補全/<UP>
: 直接調用上次的查找邏輯./<DOWN>
: 直接調用下次的查找邏輯./<C-N>
: 直接調用下次的查找邏輯./<C-P>
: 直接調用上次的查找邏輯./<C-r>/
: 使用寄存器 /
將上次查找的值直接插入到當前模式中來/pattern/[e]
oop
/view
: 全文查找 view 關鍵字 (n 爲向下方向)?view
: 全文查找 view 關鍵字 (n 爲向上方向)/\cview
: 全文查找 view 關鍵字(大小寫不敏感)/view/e
: 默認的查找會將光標置於單詞首部, 使用 e
保證光標位於尾部, 方便 .
命令的調用//e
: 匹配 pattern
爲空則直接重用上次的邏輯進行查找/\<f\>
: 使用 <
與 >
限定詞首與詞尾, 保證只查找單詞 f
/^\n\{3}
: 查找三個空行還有一種是使用 global
命令: :g/pattern/d
, 含義是對 patter 進行匹配搜索, 而後執行命令 delete
, 也是基於查找的ui
\r
: 換行, 在 pattern 中使用\n
做爲搜索串, 在string 中使用\r
做爲換行命令(若是在 string 中仍然使用 \n 的話會出錯)\u
或 \l
: 把替換串中的下一個字符分別變成大寫或者小寫.~
: 用在替換串中, 表明使用上次的替換串.&
: 用在替換串, 它表明與搜索模式想匹配的整個文本, 即「重現」搜索串. 這在試圖避免重複輸入文本時頗有用.\U
和 \L
: 將跟在後面的匹配串所有變成大寫或小寫[range]s/pattern/string/[c,e,g,i]
spa
range
: 範圍, 1,7
指第一行至第七行. 也可使用 %
表明當前的文章(也能夠理解爲所有的行), #
表明前一次編輯的文章(基本不用)s
: 表明當前的模式爲替換/
: 做爲分隔符, 若是確實要替換文中的 /
, 那麼可使用 #
代替做爲分隔符. 例如 :s#vi/#vim#g
, 表明替換 vi/
爲 vim
pattern
: 要被替換掉的字符string
: 將要使用的字符c
: confirm, 每次替換前會詢問e
: ignore, 忽略錯誤(默認找不到會提示 pattern not found
, 可是若是設置 vim 設置批量替換命令的話某一個項未匹配到不能影響到下一項的執行, 可使用此關鍵字, :silent %s/x/y/g
== :%s/x/y/ge
)g
: global, 整行替換(基本上是必加的, 不然只會替換每一行的第一個符合字符)i
: ignore, 不區分大小寫I
: 區分大小寫在表達式中可使用 \(
與 \)
將表達式括起來, 而後既可在後面使用 \1
\2
來依次訪問由 \(
與 \)
包圍起來的內容.插件
例: :s/\(\w\+\)\s\+\(\w\+\)/\2\t\1
表示將 data1 data2 修改成 data2 data1
r
: 進入單字符替換模式R
: 進入替換模式&
: 重複上次的替換過程:s/vi/vim/
: 只替換當前行的第一個 vi 爲 vim:s/vi/vim/g
: 替換當前行的全部 vi 爲 vim:%s/vi/vim/g
: 替換全文全部 vi 爲 vim:%s/vi/vim/gi
: 替換全文全部 vi 爲 vim, 大小寫不敏感:n,$s/vi/vim/gci
: 替換從第 n 行到結尾全部 vi 爲 vim, 每次替換提示, 不區分大小寫:.,$s/vi/vim/gci
: 替換從當前行到結尾全部 vi 爲 vim, 每次替換提示, 不區分大小寫:.,+3s/^/#
: 在當前行到下面三行添加 #
的註釋:g/^\s*$/d
: 刪除全部空行:215,237 s/\(.\)$/\1(自定義)/c
: 將 215 至 237 行尾部添加 (自定義)
:%s/^\n$//gc/
: 替換多個空行爲一個空行:122,250s/\(201\d*\)\.\(\d*\)\.\(\d*\)\s/\1-\2-\3_/gc
: 替換 2017.12.31
類型的字段爲2017-12-31_
%s/\(\](http:.*com\/\)\(HK.*\))/\](https:\/\/a.hanleylee.com\/\2?x-oss-process=style\/WaMa)/gc
: 將[](http: ....com)
替換成 https 而且尾部帶有樣式參數:%s/\(a.*bc\)\(<.*>\)\(xy.*z\)/\3\2\1/gc
: 使用緩衝塊實現對先後區域匹配並翻轉位置(須要時再理解):%s/hello/&, world/
: 將會把hello替換成hello, wolrd:%s/.*/(&)/
: 將會把全部行用()包含起來: s/world/\U&/
: 把 world 變成 WORLD:%s ; /user1/tim;/home/time;g
: /user1/tim改成/home/time, 除了/字符外, 還可使用除反斜杆, 雙引號和豎直線 \
, "
, 和 |
, 以外的任何非字母表, 非空白字符做爲分隔符, 在對路徑名進行修改時, 這點尤爲便利:s
: 與 :s//~/
相同, 重複上次替換:&
: 重複上次替換%s/\<child\>/children/g
: 保證在 child 是個完整單詞的狀況下進行替換:g/mg[ira]box/s/box/square/g
: 將 mgibox routine, mgrbox routine, mgabox routine,
中的 box 換爲 square&
: 直接使用 & 也是重複上次替換的意思替換時系統會對用戶進行詢問, 有 (y/n/a/q/1/^E/^Y
)
y
: 表示贊成當前替換n
: 表示不一樣意當前 替換a
: 表示替換當前和後面的而且再也不確認q
: 表示當即結束替換操做1
: 表示把當前的替換後結束替換操做;^E
: 向上滾屏^Y
: 向下滾屏,多文件操做的基礎是必定要 設置好工做目錄, 由於添加文件到操做列表是以當前路徑下的文件進行判斷篩選的, 設置當前路徑可以使用如下方式:
:cd path
NERDTree
插件的 cd
命令netrw
插件的 cd
命令.vimrc
中設置 set autochair
自動切換當前工做路徑vimgrep /pattern/[g][j] <range>
vimgrep
: 批量查找命令, 其後可直接加 !
表明強制執行. 也可使用lvimgrep
, 結果顯示在 list 中patten
: 須要查找的內容, 支持正則表達式, 高級用法見元字符g
: 若是一行中有多個匹配是否所有列出j
: 搜索完後直接定位到第一個匹配位置range
: 搜索的文件範圍
%
: 在當前文件中查找**/*.md
: 在當前目錄即子目錄下的全部 .md 文件中*
: 當前目錄下查找全部(不涉及子目錄)**
: 當前目錄及子目錄下全部*.md
: 當前目錄下全部.md 文件**/*
: 只查找子目錄查找的結果使用 quick-fix
來進行展現, 可以使用 :copen
查看全部結果項並進行相應跳轉, 具體操做參考 神級編輯器 Vim 使用-操做篇
:vimgrep /hello/g **
: 在當前目錄及子目錄下的全部文件內查找 hello
字符串quickfix-list 是一個完整的窗口, 能夠移動上下光標, 按下 enter 進行打開文件
location-list 只是一個局部的顯示區域, 只能簡單顯示查找結果的信息, 目前看來沒有必要使用此選項
多文件替換所依賴的是 vim 中的參數列表概念, 這裏僅對流程命令進行演示, 具體的參數列表操做參考 神級編輯器 Vim 使用-操做篇
args
: 顯示當前的全部參數列表:args *.md aa/**/*.md
表示添加子文件夾下的 md
文件及 aa
文件夾下的和其子文件夾下的 md
文件到參數列表中:argdo %s/oldword/newword/egc | update
: 對全部存在參數列表中的文件執行命令, s
表明替換, %
指對全部行進行匹配, g
表明整行替換(必用), e
指使用正則表達式, c
表明每次替換前都會進行確認, update
表示對文件進行讀寫:argdo %s/!\[.*\]/!\[img\]/gc
: 將全部參數列表中的以 ![
開頭, 以 ]
結尾的全部字段改成 [img]
:argdo write
: 將全部參數列表中的內容進行緩衝區保存本文做者 Hanley Lee, 首發於 閃耀旅途, 若是對本文比較承認, 歡迎 Follow