九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
神級編輯器 Vim 使用-正則操作篇
userphoto

2022.08.16 北京

關注

Vim 的替換查找是其核心功能, 功能極其強大, 通過其規(guī)則匹配, 可以很快速地完成我們很多需要大量人力操作的工作, 而且可對多文件使用查找/替換功能.

本系列教程共分為以下五個部分:

  1. 神級編輯器 Vim 使用-基礎篇
  2. 神級編輯器 Vim 使用-操作篇
  3. 神級編輯器 Vim 使用-插件篇
  4. 神級編輯器 Vim 使用-正則操作篇
  5. 神級編輯器 Vim 使用-最后

正則匹配的模式

編程界實現了多種正則匹配引擎, vim 的正則匹配引擎是獨有的, 其風格類似于 POSIX, 但是我們可通過將其匹配模式設為:

  • \v: (very magic) 來開啟 Perl 模式, 此模式下 ( 已經被轉義, 如果要搜索 (, 必須轉回原義: \((此模式實際上最接近大部分語言中的正則)
  • \V: (very nomagic) 來開啟開啟原義模式, 此模式下直接搜索( 即可搜索到 (
  • \m: 默認模式, 不指定任何模式時使用的就是此模式. 此模式下僅部分字符有特殊含義, ( 沒有被轉義, 仍然可通過 ( 搜索到 (
  • \M: (nomagic) 其功能類似于 \V 原義開關, 不同的是, 一些字符會自動具有特殊含義, 即符號 ^$

本文只討論默認模式下(\m 模式)下的正則匹配, 其他模式下的原理類似, 讀者可自行研究

查找

查找元字符

元字符是正則匹配的一個概念, 通過元字符可以快速找出目標字段.

  • .: 表示匹配任意 一個 字符. 例: 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 ..., 貪婪匹配模式

  • \{-}: 非貪婪匹配模式, non-greedy, 與 * 相對, .\{-}.* 一樣表示匹配任意多個字符

  • \?\=: 代表其前字符必須重復 0 或者 1 次.

  • \{n,m} : 其前字符必須重復 n 到 m 次, 貪婪匹配模式. (\{n,} 表示右邊界范圍為無限, {,m} 表示左邊界范圍為0)

  • \n: 其前字符必須重復 n 次

  • \{-n,m} : 其前字符必須重復 n 到 m 次, 非貪婪匹配模式. (\{-n,} 表示右邊界范圍為無限, {-,m} 表示左邊界范圍為0)

  • [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]

  • \o: 匹配八進制數字外的任意一個字符

  • \O: 匹配除八進制數字外的任意一個字符

  • \h: head of word character(a,b,c...z,A,B,C...Z,_), 等同于 [a-zA-Z_]

  • \H: non-head of word character, 等同于 [^a-zA-Z_]

  • \a: alphabetical character, 等同于 [a-zA-Z]

  • \A: non-alphabetical character, 等同于 [^a-zA-Z]

  • \l: lowercase character

  • \L: non-lowercase character

  • \u: uppercase character

  • \U: non-uppercase character

  • \w: 匹配一個單詞(對中文來說非常雞肋, 因為只有 Vim 判定是單詞的才會進行匹配, 與normal 模式下的 w, b, e 匹配規(guī)則相同)

  • \W: 匹配除單詞外的所有字符. 因為在 vim 中中文全部不被認為是單詞, 因此, 此匹配會選中所有中文字段.

  • \t: 代表 tab , 可使用此方法將所有 tab 替換為空格

  • \s: 配空白字段, 包含 tab 與空格, 在 pattern 中使用此查找空白, 在 string 中就可以直接使用空格或者 tab 來輸入以替換了

  • \S: 匹配非空白字段, 等同于 [^\s]

  • \n: 匹配換行符

  • \_s: 匹配換行或空白(空格或 tab)

  • \_a: 匹配換行或單詞(因為是單詞, vim 不會匹配中文)

  • \C: 區(qū)分大小寫地查找或替換, 例: /\CText 表示只會查找Text, 不會查找 texttExt

  • \c: 不區(qū)分大小寫地查找替換(已經在 vim 中設置了默認不區(qū)分了)

  • \zs: set the beginning of the match

  • \ze: set the end of the match

  • \<: beginning of word, zero width match

  • \>: end of word, zero width match

  • \%^: beginning of file, zero width match

  • \%$: end of file, zero width match

  • \@!: negative look-ahead

  • \_@<!: negative look-behind

如上所述, ., *, [, ], ^, %, /, ?, ~, $ 等字符有特殊含義, 如果對這些進行匹配, 需要考慮添加 \

查找邏輯

/pattern/[se]

查找實例

  • /view: 全文查找 view 關鍵字 (n 為向下方向)
  • ?view: 全文查找 view 關鍵字 (n 為向上方向)
  • /\cview: 全文查找 view 關鍵字(大小寫不敏感)
  • :100,235g/foo/#: 在區(qū)間 100 ~ 235 搜索, 在控制臺輸出結果
  • :100,235il foo: 同上
  • /view/e: 默認的查找會將光標置于單詞首部, 使用 e 保證光標位于尾部, 方便 . 命令的調用
  • /view/s-2: cursor set to start of match minus 3
  • /view/+3: find view move cursor 3 lines down
  • /^joe.*fred.*bill/: find joe and bill(joe at start of line)
  • /^[A-J]: search for lines beginning with one or more A-J
  • /begin\_.*end: search over possible multiple lines
  • /fred\_s*joe: any whitespace including newline
  • /fred\|joe: search for fred or joe
  • /.*fred\&.*joe: search for fred and joe in any order
  • /\<fred\>/: search fro fred but not alfred or frederick
  • /\<\d\d\d\d\>: search for exactly 4 digit numbers
  • /\D\d\d\d\d\D: search for exactly 4 digit numbers
  • /\<\d\{4}\>: same thing
  • /\([^0-9]\|^\)%.*%: search for absence of a digit or beginning of line
  • /^\n\{3}: find 3 empty lines
  • /^str.*\nstr: find 2 successive lines starting with str
  • /\(^str.*\n\)\{2}: find 2 successive lines starting with str
  • /\(fred\).*\(joe\).*\2.*\1
  • /^\([^,]*,\)\{8}
  • :vmap // y/<C-R>"<CR>: search for visually highlighted text
  • :vmap <silent> // y/<C-R>=escape(@", '\\/.*$^~[]')<CR><CR>: with spec chars
  • /<\zs[^>]*\ze>: search for tag contents, ignoring chevrons
  • /<\@<=[^>]*>\@=: search for tag contents, ignoring chevrons
  • /<\@<=\_[^>]*>\@=: search for tags across possible multiple lines
  • /\%(defg\)\@<!abc: anything starting with abc that's not (immediately) preceeded by defg
  • /\%(defg.*\)\@<!abc: match abc as long as it's not part of defg.*abc
  • /\%(defg.*\)\@<!abc \%(.*defg\)\@!: Matching abc only on lines where defg doesn't occur is similar
  • /<!--\_p\{-}-->: search for multiple line comments
  • /fred\_s*joe/: any whitespace including newline
  • /bugs\(\_.\)*bunny: bugs followed by bunny anywhere in file
  • /\c\v([^aeiou]&\a){4}: search for 4 consecutive consonants
  • /\%>20l\%<30lgoat: search for goat between lines 20 and 30
  • /^.\{-}home.\{-}\zshome/e: match only the 2nd occurence in a line of home
  • /^\(.*tongue.*\)\@!.*nose.*$
  • \v^((tongue)@!.)*nose((tongue)@!.)*$
  • .*nose.*\&^\%(\%(tongue\)\@!.\)*$
  • :v/tongue/s/nose/&/gic
  • 'a,'bs/extrascost//gc: trick: restrict search to between markers
  • /integ<C-L>: Control-L to complete term
  • //e: 匹配 pattern 為空則直接重用上次的邏輯進行查找
  • /\<f\>: 使用 <> 限定詞首與詞尾, 保證只查找單詞 f
  • /^\n\{3}: 查找三個空行
  • /\s\{2,}: 查找 2 個以上的空格
  • /he\zsllo: 查找 hello 并將 llo 作為匹配點進行高亮
  • /abc\(defg\)\@!: 只查找 abc, 且后面不跟隨 defg, 否則不匹配, \@! 表示 negative look-ahead assertion, 查看幫助 help \@!
  • /printer_\@!: find any printer that is not followed by an _
  • /_\@<!printer: find any printer that is not begin with an _
  • `[^`]\_.\{-0,}`: 以 ` 開頭, 以 ` 結尾, 且中間內容超過一個字符, 且內容可以跨行

還有一種是使用 global 命令: :g/pattern/d , 含義是對 patter 進行匹配搜索, 然后執(zhí)行命令 delete, 也是基于查找的

查找時的常用操作

  • :noh : 取消查找模式的高亮匹配
  • *: 全文查找當前光標處單詞 (n 為向下方向)
  • #: 全文查找當前光標處單詞 (n 為向上方向)
  • n: 下一個列出的關鍵字
  • N: 上一個列出的關鍵字
  • gn: 進入面向字符的可視模式, 并選中下一項匹配
  • gN: 進入面向字符的可視模式, 并選中上一項匹配
  • gUgn: 使下一處匹配改為大寫
  • <C-r><C-w>: 根據當前查找模式下已經輸入的內容結合全文進行自動補全
  • /<UP>: 直接調用上次的查找邏輯.
  • /<DOWN>: 直接調用下次的查找邏輯.
  • /<C-n>: 直接調用下次的查找邏輯.
  • /<C-p>: 直接調用上次的查找邏輯.
  • /<C-r>/: 使用寄存器 / 將上次查找的值直接插入到當前模式中來

替換

替換元字符

  • \r: 換行, 在 pattern 中使用\n 作為搜索串, 在string 中使用\r 作為換行命令(如果在 string 中仍然使用 \n 的話會出錯)
  • \u\l: 把替換串中的下一個字符分別變成大寫或者小寫.
  • ~: 用在替換串中, 代表使用上次的替換串.
  • &: 用在替換串, 它代表與搜索模式想匹配的整個文本, 即“重現”搜索串. 這在試圖避免重復輸入文本時很有用.
  • \0: 同 &
  • \1: 匹配到的第一個 \(...\)
  • \2: 匹配到的第二個 \(...\)
  • \U: 將跟在后面的匹配串全部變成大寫
  • \L: 將跟在后面的匹配串全部變成小寫
  • \E / \e: end of \U and \L
  • \l: next character made lowercase
  • \u: next character made uppercase

替換邏輯

:[range]s/pattern/string/flags

  • range: 范圍
    • : 默認光標所在的行
    • .: 光標所在的當前行
    • N: 第 N 行
    • $: 最后一行
    • 'a: 標記 a 所在的行(使用 ma 標記的)
    • .+1: 當前光標的下面一行
    • $-1: 倒數第二行
    • 22,23: 第22 ~ 23行
    • 1,$: 第一行到最后一行
    • 1,.: 第一行到當前行
    • .,$: 當前行到最后一行
    • 'a, 'b: 標記 a 所在的行到 標記 b 所在的行
    • %: 所有行(與 1,$ 等價)
    • ?str?: 從當前位置向上搜索, 找到的第一個 str 所在的行(str 可以為正則表達式)
    • /str/: 從當前位置向下搜索, 找到的第一個 str 所在的行
    • 1,7 指第一行至第七行. 也可以使用 % 代表當前的文章(也可以理解為全部的行), # 代表前一次編輯的文章(基本不用)
  • s : 代表當前的模式為替換
  • /: 作為分隔符, 如果確實要替換文中的 /, 那么可以使用 # 代替作為分隔符. 例如 :s#vi/#vim#g, 代表替換 vi/vim
  • pattern : 要被替換掉的字符
  • string : 將要使用的字符
  • flags
    • : 只對指定范圍內的每一行的第一個匹配項進行替換
    • g : global, 整行替換(基本上是必加的, 否則只會替換每一行的第一個符合字符)
    • c : confirm, 每次替換前會詢問
    • e: ignore, 忽略錯誤(默認找不到會提示 pattern not found, 但是如果設置 vim 設置批量替換命令的話某一個項未匹配到不能影響到下一項的執(zhí)行, 可以使用此關鍵字, :silent %s/x/y/g == :%s/x/y/ge )
    • i : ignore, 不區(qū)分大小寫
    • I: 區(qū)分大小寫

變量替換

在表達式中可以使用 \(\) 將表達式括起來, 然后既可在后面使用 \1 \2 來依次訪問由 \(\) 包圍起來的內容.

例: :s/\(\w\+\)\s\+\(\w\+\)/\2\t\1 表示將 data1 data2 修改為 data2 data1

替換實例

  • r : 進入單字符替換模式
  • R : 進入替換模式
  • :&: 重復上次替換
  • :%&: last substitute every line
  • :%&gic: last substitute every line confirm
  • g%: normal mode repeat last substitute
  • g&: last substitute on all lines
  • &: 直接使用 & 也是重復上次替換的意思
  • :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, 每次替換提示, 不區(qū)分大小寫
  • :.,$s/vi/vim/gci : 替換從當前行到結尾所有 vi 為 vim, 每次替換提示, 不區(qū)分大小寫
  • :.,+3s/^/#: 在當前行到下面三行添加 # 的注釋
  • :g/^\s*$/d : 刪除所有空行
  • :g/^$/d : 刪除所有空行
  • :%s/\s*$//g: 刪除行尾空格
  • :%s/^\s*//g: 刪除行首空格
  • :215,237 s/\(.\)$/\1(自定義)/c: 將 215 至 237 行尾部添加 (自定義)
  • :%s/^\n$//gc/ : 替換多個空行為一個空行
  • :s:\s\+$::: a simple regexp I use quite often to clean up a text: it drops the blanks at the end of the line.
  • :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: 使用緩沖塊實現對前后區(qū)域匹配并翻轉位置(需要時再理解)
  • :%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
  • :%s/fred/joe/igc: general substitute command
  • :%s//joe/igc: substitute your last replacement string
  • :%s/~/sue/igc: substitute your last replacement string
  • :%s/\r//g: delete DOS return ^M
  • :%s/\r/\r/g: turn DOS return ^M into real returns
  • :%s= *$==: delete end of line blanks
  • :%s= \+$==: Same thing
  • :%s#\s*\r\?$##: Clean both trailing spaces AND DOS returns
  • :%s#\s*\r*$##: same thing
  • :%s/^\n\{3}//: delete blocks of 3 empty lines
  • :%s/^\n\+/\r/: compressing empty lines
  • :%s#.*\(\d\+hours\).*#\1#: delete all but memorised string
  • :%s#><\([^/]\)#>\r<\1#g : split jumbled up XML file into one tag per line [N]
  • :%s/</\r&/g : simple split of html/xml/soap [N]
  • :%s#<[^/]#\r&#gic : simple split of html/xml/soap but not closing tag [N]
  • :%s#<[^/]#\r&#gi : parse on open xml tag [N]
  • :%s#\[\d\+\]#\r&#g : parse on numbered array elements [1] [N]
  • ggVGgJ : rejoin XML without extra spaces (gJ) [N]
  • :%s=\\n#\d=\r&=g : parse PHP error stack [N]
  • :%s#^[^\t]\+\t## : Delete up to and including first tab [N]
  • :'a,'bg/fred/s/dick/joe/igc : VERY USEFUL
  • :%s= [^ ]\+$=&&= : duplicate end column
  • :%s= \f\+$=&&= : Dupicate filename
  • :%s= \S\+$=&& : usually the same
  • :%s#example#& = &#gic : duplicate entire matched string [N]
  • :%s#.*\(tbl_\w\+\).*#\1# : extract list of all strings tbl_* from text [NC]
  • :s/\(.*\):\(.*\)/\2 : \1/ : reverse fields separated by :
  • :%s/^\(.*\)\n\1$/\1/ : delete duplicate lines
  • :%s/^\(.*\)\(\n\1\)\+$/\1/ : delete multiple duplicate lines [N]
  • :%s/^.\{-}pdf/new.pdf/ : delete to 1st occurence of pdf only (non-greedy)
  • :%s#^.\{-}\([0-9]\{3,4\}serial\)#\1#gic : delete up to 123serial or 1234serial [N]
  • :%s#\<[zy]\?tbl_[a-z_]\+\>#\L&#gc : lowercase with optional leading characters
  • :%s/<!--\_.\{-}-->// : delete possibly multi-line comments
  • :s/fred/<c-r>a/g : sub "fred" with contents of register "a"
  • :s/fred/<c-r>asome_text<c-r>s/g
  • :s/fred/\=@a/g : better alternative as register not displayed
  • :s/fred/\=@*/g : replace string with contents of paste register
  • :%s/\f\+\.gif\>/\r&\r/g | v/\.gif$/d | %s/gif/jpg/
  • :%s/a/but/gie|:update|:next : then use @: to repeat
  • :%s/goat\|cow/sheep/gc : ORing (must break pipe)
  • :'a,'bs#\[\|\]##g : remove [] from lines between markers a and b [N]
  • :%s/\v(.*\n){5}/&\r : insert a blank line every 5 lines [N]
  • :s/__date__/\=strftime("%c")/ : insert datestring
  • :inoremap \zd <C-R>=strftime("%d%b%y")<CR> : insert date eg 31Jan11 [N]
  • :%s:\(\(\w\+\s\+\)\{2}\)str1:\1str2:
  • :%s:\(\w\+\)\(.*\s\+\)\(\w\+\)$:\3\2\1:
  • :%s#\<from\>\|\<where\>\|\<left join\>\|\<\inner join\>#\r&#g
  • :redir @*|sil exec 'g#<\(input\|select\|textarea\|/\=form\)\>#p'|redir END
  • :nmap ,z :redir @*<Bar>sil exec 'g@<\(input\<Bar>select\<Bar>textarea\<Bar>/\=form\)\>@p'<Bar>redir END<CR>
  • :%s/^\(.\{30\}\)xx/\1yy/: substitute string in column 30 [N]
  • :%s/\d\+/\=(submatch(0)-3)/: decrement numbers by 3
  • :g/loc\|function/s/\d/\=submatch(0)+6/: increment numbers by 6 on certain lines only
  • :%s#txtdev\zs\d#\=submatch(0)+1#g
  • :%s/\(gg\)\@<=\d\+/\=submatch(0)+6/ : increment only numbers gg\d\d by 6 (another way)
  • :let i=10 | 'a,'bg/Abc/s/yy/\=i/ |let i=i+1: convert yy to 10,11,12 etc
  • :let i=10 | 'a,'bg/Abc/s/xx\zsyy\ze/\=i/ |let i=i+1 # convert xxyy to xx11,xx12,xx13
  • :%s/"\([^.]\+\).*\zsxx/\1/
  • :vmap <leader>z :<C-U>%s/\<<c-r>*\>/
  • :'a,'bs/bucket\(s\)*/bowl\1/gic
  • :%s,\(all/.*\)\@<=/,_,g : replace all / with _ AFTER "all/"
  • :s#all/\zs.*#\=substitute(submatch(0), '/', '_', 'g')#
  • :s#all/#&^M#|s#/#_#g|-j! : Substitute by splitting line, then re-joining
  • :%s/.*/\='cp '.submatch(0).' all/'.substitute(submatch(0),'/','_','g')/ : Substitute inside substitute
  • :%s/home.\{-}\zshome/alone: substitute only the 2nd occurence of home in any line
  • :%s/.*\zsone/two/: substitute only the last occurrence of one

替換時系統(tǒng)會對用戶進行詢問, 有 (y/n/a/q/1/^E/^Y)

  • y : 表示同意當前替換
  • n : 表示不同意當前 替換
  • a : 表示替換當前和后面的并且不再確認
  • q : 表示立即結束替換操作
  • 1 : 表示把當前的替換后結束替換操作;
  • ^E : 向上滾屏
  • ^Y : 向下滾屏,

Global

global 語法有兩種

  1. :[range]g:/{pattern}/[cmd]: 在 range 內搜索 pattern, 如果符合要求就執(zhí)行 cmd
  2. :g/pattern1/, /pattern2/[cmd]: 在 /p1/, p2/ 之間執(zhí)行 cmd
  • :g/re/d: 刪除所有匹配到 re 的行
  • :g/re/p: 打印所有匹配到 re 的行
  • :g//d: 使用上次的查找結果進行匹配然后刪除
  • :g/^$/,/./-j: reduce multiple blank to a single blank
  • :10,20g/^/ mo 10: reverse the order of the lines starting from the line 10 up to the line 20.
  • :'a,'b g/^Error/ . w >> errors.txt: in the text block marked by 'a and 'b find all the lines starting with Error and copy (append) them to errors.txt file. Note: . (current line address) in front of the w is very important, omitting it will cause :write to write the whole file to errors.txt for every Error line found.
  • :g/^Error:/ copy $ | s /Error/copy of the error/: will copy all Error line to the end of the file and then make a substitution in the copied line. Without giving the line address :s will operate on the current line, which is the newly copied line.
  • :g/^Error:/ s /Error/copy of the error/ | copy $: here the order is reversed: first modify the string then copy to the end.
  • :v/re/d: vglobal 的反面, 只保留匹配到 re 的行
  • :g/TODO/yank A: 將結果匹配到 TODO 的行復制到寄存器 a 的原內容尾部
  • :g/TODO/t$: 將結果匹配到 TODO 的行復制到本緩沖區(qū)的尾部
  • :g/{/.+1,/}/-1 sort: 會在每個 { 開始找, 然后在之后一直執(zhí)行到 } 為止, 進行排序
  • :g/{/sil.+1,/}/-1 >: 會在每個 { 開始找, 然后在之后一直執(zhí)行到 } 為止, 進行縮進 (加入 sil 是為了屏蔽提示信息)
  • :g/ 從這里刪除 /.,$ d: 從內容中搜出的第一個 從這里刪除 開始, 一直刪除到文章結尾
  • :g/^\(.*\)$\n\1$/d: 去除重復行
  • :g/\%(^\1$\n\)\@<=\(.*\)$/d: 去除重復行
  • :g/\%(^\1\>.*$\n\)\@<=\(\k\+\).*$/d: 去除重復行
  • :g/gladiolli/#: display with line numbers
  • :g/gred.*joe.*dick/: display all lines fred, joe & dick
  • :g/\<fred\>/ : display all lines fred but not freddy
  • :g/^\s*$/d: delete all blank lines
  • :g!/^dd/d: delete lines not containing string
  • :v/^dd/d: delete lines not containing string
  • :g/joe/,/fred/d: not line based
  • :g/joe/,/fred/j: join lines
  • :g/-----/.-10,.d: delete string & 10 previous lines
  • :g/{/ ,/}/- s/\n\+\r/g: delete empty lines but only between {...}
  • :v/\S/d: delete empty lines
  • :v/./,/./-j: compress empty lines
  • :g/^$/,/./-j: compress empty lines
  • :g/<input\|<form/p:ORing
  • :g/^/put_: double space file (pu = put)
  • :g/^/m0: reverse file(m = move)
  • :g/^/m$: no effect!
  • :'a,'bg/^/m'b: reverse a section a to b
  • :g/^t.: duplicate every line
  • :g/fred/t$: copy(transfer) lines matching fred to EOF
  • :g/stage/t'a: copy(transfer) lines matching stage to marker a
  • :g/^chapter/t.|s/./-/g: automatically underline selecting headings
  • :g/\(^I[^^I]*\)\{80}/d: delete all lines containing at least 80 tabs
  • :g/^/ if line('.')%2|s/^/zz / : perform a substitute on every other line
  • :'a,'bg/somestr/co/otherstr/ : co(py) or mo(ve)
  • :'a,'bg/str1/s/str1/&&&/|mo/str2/ : as above but also do a substitution
  • :%norm jdd : delete every other line
  • :.,$g/^\d/exe "norm! \<c-a>": increment numbers " incrementing numbers (type <c-a> as 5 characters)
  • :'a,'bg/\d\+/norm! ^A : increment numbers
  • :g/fred/y A : append all lines fred to register a
  • :g/fred/y A | :let @*=@a : put into paste buffer
  • :g//y A | :let @*=@a : put last glob into paste buffer [N]
  • :let @a=''|g/Barratt/y A |:let @*=@a
  • :'a,'bg/^Error/ . w >> errors.txt : filter lines to a file (file must already exist)
  • :g/./yank|put|-1s/'/"/g|s/.*/Print '&'/ : duplicate every line in a file wrap a print '' around each duplicate
  • :g/^MARK$/r tmp.txt | -d : replace string with contents of a file, -d deletes the "mark"
  • :g/<pattern>/z#.5 : display with context
  • :g/<pattern>/z#.5|echo "==========" : display beautifully
  • :g/|/norm 2f|r* : replace 2nd | with a star
  • :nmap <F3> :redir @a<CR>:g//<CR>:redir END<CR>:new<CR>:put! a<CR><CR>
  • :'a,'bg/fred/s/joe/susan/gic : can use memory to extend matching
  • :/fred/,/joe/s/fred/joe/gic : non-line based (ultra)
  • :/biz/,/any/g/article/s/wheel/bucket/gic: non-line based [N]
  • :/fred/;/joe/-2,/sid/+3s/sally/alley/gIC
  • :g/^/exe ".w ".line(".").".txt" : create a new file for each line of file eg 1.txt,2.txt,3,txt etc
  • :.g/^/ exe ".!sed 's/N/X/'" | s/I/Q/ : chain an external command
  • :g/^$/;/^$/-1!sort: Sort each block (note the crucial ;)

Operate until string found

  • d/fred/: delete until fred
  • y/fred/: yank until fred
  • c/fred/e: change until fred end
  • v12|: visualise/change/delete to column 12

正則相關的 vimscript 方法

  • 'a' =~# '\a': 匹配返回 1, 不匹配返回 0, 不忽略大小寫
  • 'a' =~? '\a': 同上, 但忽略大小寫
  • 'a'!~# '\a': 匹配返回 0, 不匹配返回 1, 不忽略大小寫
  • 'a'!~? '\a': 同上, 但忽略大小寫
  • substitute( {expr}, {pat}, {sub}, {flags}): 使用 flags, 替換 expr 里面的 pat (即 pattern 表示的正則) 為 sub
  • match( {expr}, {pat}[, {start}[, {count}]]): 返回 patexpr 里面所匹配的位置, 可設置開始位置和重復次數
  • matchend( {expr}, {pat}[, {start}[, {count}]]): 跟 match 函數一樣, 但是返回最后一個字符的匹配位置
  • matchlist({expr}, {pat}[, {start}[, {count}]]): 返回匹配的列表, 第一項是完整匹配, 后面是其它子匹配項
  • matchstr({expr}, {pat}[, {start}[, {count}]]): 返回 expr 里面 pat 所匹配的字符串, 無匹配返回空字符串

正則表達式執(zhí)行順序

以下由最高優(yōu)先級至最低進行排列

Precedence Regexp Description
1 \( \) grouping
2 \=,\+,*,\{n} etc. quantifiers
3 abc\t\.\w sequence of characters/ metacharacters, not containing quantifiers or grouping operators
4 | alternation

多文件查找與替換

多文件操作的基礎是一定要 設置好工作目錄, 因為添加文件到操作列表是以當前路徑下的文件進行判斷篩選的, 設置當前路徑可使用以下方式:

  • 手動 :cd path
  • NERDTree 插件的 cd 命令
  • netrw 插件的 cd 命令
  • .vimrc 中設置 set autochair 自動切換當前工作路徑

多文件查找

邏輯

vimgrep /pattern/[g][j] <range>

  • vimgrep: 批量查找命令, 其后可直接加 ! 代表強制執(zhí)行. 也可以使用lvimgrep , 結果顯示在 list 中
  • patten: 需要查找的內容, 支持正則表達式, 高級用法見元字符
  • g: 如果一行中有多個匹配是否全部列出
  • j: 搜索完后直接定位到第一個匹配位置
  • range : 搜索的文件范圍
    • %: 在當前文件中查找
    • **/*.md: 在當前目錄即子目錄下的所有 .md 文件中
    • *: 當前目錄下查找所有(不涉及子目錄)
    • ** : 當前目錄及子目錄下所有
    • *.md : 當前目錄下所有.md 文件
    • **/* : 只查找子目錄

查找的結果使用 quick-fix 來進行展示, 可使用 :copen 查看所有結果項并進行相應跳轉, 具體操作參考 神級編輯器 Vim 使用-操作篇

實例

  • :vimgrep /hello/g **: 在當前目錄及子目錄下的所有文件內查找 hello 字符串

quickfix-list 與 location-list 的區(qū)別

quickfix-list 是一個完整的窗口, 可以移動上下光標, 按下 enter 進行打開文件

location-list 只是一個局部的顯示區(qū)域, 只能簡單顯示查找結果的信息, 目前看來沒有必要使用此選項

多文件替換

多文件替換所依賴的是 vim 中的參數列表概念, 這里僅對流程命令進行演示, 具體的參數列表操作參考 神級編輯器 Vim 使用-操作篇

  • :args: 顯示當前的所有參數列表
  • :args *.md aa/**/*.md 表示添加子文件夾下的 md 文件及 aa 文件夾下的和其子文件夾下的 md 文件到參數列表中
  • :argdo %s/oldword/newword/egc | update : 對所有存在參數列表中的文件執(zhí)行命令, s 代表替換, % 指對所有行進行匹配, g 代表整行替換(必用), e 指使用正則表達式, c 代表每次替換前都會進行確認, update 表示對文件進行讀寫
  • :argdo %s/!\[.*\]/!\[img\]/gc: 將所有參數列表中的以 ![ 開頭, 以 ] 結尾的所有字段改為 [img]
  • :argdo write: 將所有參數列表中的內容進行緩沖區(qū)保存

最后

我的 vim 配置倉庫: HanleyLee/dotvim

本文作者 Hanley Lee, 首發(fā)于 閃耀旅途, 如果對本文比較認可, 歡迎 Follow

參考

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
VIM中的搜索和替換
在 Vim 中優(yōu)雅地查找和替換
學會這21條,你離 Vim 大神就不遠了!
vim編輯器常用命令總結
vi/vim編輯器使用方法詳解
vim編輯器教程
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服