vim 底行命令模式的正则表达式(匹配模式)
文章目錄
- 一、vim 替換表達式的語法格式
- 二、vim 關于 range 的表達式
- 三、vim 關于 flags 的元字符
- 四、vim 關于數量的元字符
- 五、環視和固化分組
- 六、vim 替換表達式的示例
- (一)結合 copy 命令使用
- (二)結合 move 命令使用
- (三)結合 normal 命令使用
- (四)匹配重復性模式
- (五)指定重復次數
- (六)匹配可選項
- (七)多選一匹配模式/多選結構
- (八)引用分組
- (九)替換內容的特殊字符
- 1. & 符號
- 2. ~ 符號
- 3. \u 和 \l
- 4. \U 和 \L
- (十)界定 pattern 的子集
一、vim 替換表達式的語法格式
語法格式:[range]substitute/from/to/[flags] 或者 [range]s/src/dest/[para] 或者 [range]s/pattern/replacement/[options]
說明:substitute 命令可以對一個指定范圍的區域執行替換操作,可以簡寫為 s。該命令是將[range]所指定范圍中的字符串"from"替換為"to",“from” 可以使用正則表達式。
二、vim 關于 range 的表達式
range 意為檢索范圍,如果不指定 range,則表示當前行。vim 表示范圍或者位置的表達式或者元字符如下表所示:
| % | 整個文檔,即每一行,所有行,等價于 1,$ |
| 1 | 表示整個文檔的第一行 |
| $ | 表示行尾,這是虛擬的概念;另外還表示整個文檔的最后一行 |
| ^ | 表示行首,這是虛擬的概念 |
| 0 | 虛行,表示第一行的上方 |
| . | 當前行 |
| 'm | 包含位置標記m的行,不知道干嘛的 |
| \< | 匹配單詞詞首,在 very magic 下,不需要轉義,< 就可以匹配詞首,詳解《關于 vim 的 magic 設置》 |
| \> | 匹配單詞詞尾 |
| \zs | 界定 pattern 的子集的開始,不好理解是吧,下面的例子吧~ |
| \ze | 界定 pattern 的子集的結束 |
| '<,'> | 可視模式下的范圍,在選擇好文本內容后,按冒號 : 后自動出現 '<,'> 范圍,不用自己輸入 |
| m,n | 從m行到n行。例如,2,3 表示第二行至第三行 |
| .+3,$-5 | 作用范圍從當前行其下的第3行,到倒數第6行 |
三、vim 關于 flags 的元字符
有的表達式范例寫成 para,意思相同。
| g | 表示替換一行中的所有匹配到的源字符串,表示替換行中的所有匹配點 |
| c | 每次替換前詢問,告訴 substitute 命令要執行每個替換前請求用戶確定 |
| e | 出錯不提示 |
| i | 忽略大小寫 |
| p | 列印 |
四、vim 關于數量的元字符
表示數量的元字符,也叫“限定符”,也叫“量詞”。
| * | * | 表示任意數量(匹配優先) |
| \+ | + | 表示 1 個或多個(匹配優先) |
| \? 或 \= | ? | 表示 0 個或 1 個(匹配優先),\? 不能在 ? 命令(逆向查找)中使用 |
| \{n,m} | {n,m} | 表示 n 個到 m 個(匹配優先) |
| \{n,} | {n,} | 表示 n 個到無限個,即最少 n 個(匹配優先) |
| \{,m} | {,m} | 表示 0 個到 m 個,即最多 m 個(匹配優先) |
| \{n} | {n} | 表示 n 個 |
| \{-n,m} | {n,m}? | 表示 n 個到 m 個(忽略優先) |
| \{-} | *? | 表示任意數量(忽略優先), |
| \{-1,} | +? | 表示 1 個或多個(忽略優先) |
| \{-,1} | ?? | 表示 0 個或 1 個(忽略優先) |
注:匹配優先,是指整個正則表達式可以匹配成功的前提下,盡可能匹配更多的字符;忽略優先,是指在整個正則表達式可以匹配成功的前提下,匹配的字符數越少越好。具體可以詳見《正則表達式的貪婪模式、非貪婪模式、占有模式
》。
五、環視和固化分組
vim 還支持環視和固化分組的功能。
| \@= | (?= | 順序環視 |
| \@! | (?! | 順序否定環視 |
| \@<= | (?<= | 逆序環視 |
| \@<! | (?<! | 逆序否定環視 |
| \@> | (?> | 固化分組 |
| \%(atom\) | (?: | 非捕獲型括號 |
和 perl 稍有不同的是,vim 中的環視和固化分組的模式的位置與 perl 不同。 例如,查找緊跟在 foo 之后的 bar,perl 將模式寫在環視的括號內, 而 vim 將模式寫在環視的元字符之前。
perl 的寫法: /(?<=foo)bar/
vim 的寫法: /\(foo\)\@<=bar
六、vim 替換表達式的示例
| s/old/new | 將當前行的第一個字符串old替換為new |
| s/old/new/g | 將當前行的所有字符串old替換為new |
| 90s/old/new/g | 將第90行的所有字符串old替換為new |
| 90,93s/old/new/g | 在第 90與 93 行之間尋找old這個字符串,并將該字符串替換為 new |
| %s/old/new/g | 將文本中所有的字符串old替換為new |
| %s/old/new/gc | 在整個文檔中尋找old字符串,并將該字符串替換為new,且在替換前會顯示提示字符給用戶確認 (confirm) 是否需要取代 |
| %s/^struct/int/g | 將所有以struct開頭的字符串替換為int,^表示行首 |
| %s/^/new/g | 在每一行的行首插入new |
| 1,$s/old/new/g | 1 表示第一行,$ 表示最后一行,g 表示替換行中的所有匹配點,表達式解釋:全文查找字符串 old ,查找到后替換成字符串 new。 |
| %s/\s\+$// | 刪除行尾一個或多個空格和 tab。% 表示在所有行搜索,第一個 s 表示替換,$ 表示行尾,+ 表示一個或多個,需要使用 \ 轉義,就是 \+,第二個 s 表示空格,也要轉義,就是 \s,替換命令的 “to” 部分是空的://,正斜杠之間是空的,這樣就會刪除那些匹配的空白字符。整個表達式的解釋:在每行中查找匹配一個或者多個空格,匹配到后替換成空,也就是刪除了。 |
| %s/\s\+$ | 同上,只是把 “to” 部分省略掉 |
| %s/\s\+ | 刪除行首多余的空格和 tab,沒有使用 g,默認替換行中首次出現的源字符串,這里就是空格,所以若行首有空格,會首次匹配到,然后被替換成“空”。 |
| %s/^\s*// | 刪除行首多余空格。% 表示在所有行搜索,第一個 s 表示替換,^ 表示行首,\s 表示空格,* 表示任意數量,// 說明替換的內容為空。整個表達式的解釋:在每行的行首匹配任意數量的空格,匹配到后替換成空,也就是刪除每行行首的空格。 |
| %s/^ *// | 含義同上,這個表達式啥意思? |
| %s/^$// | 刪除沒有內容的空行。% 表示在所有行搜索,第一個 s 表示替換,^ 表示行首,$ 表示行尾,^$ 表示行首和行尾之間啥都沒有,即空行,// 說明替換的內容為空。表達式解釋:在整個文檔中檢索空行,查找到就替換為空。 |
| g/^$/d | 含義同上,這個表達式啥意思? |
| %s/^\s*$// 或者 | 刪除包含任意個空格的空行。% 表示在所有行搜索,第一個 s 表示替換,^ 表示行首,$ 表示行尾,\s 表示空格,* 表示任意數量,^\s*$ 表示包含任意數量的空格的行。表達式解釋:在整個文檔中檢索匹配包含任意個空格的行,查找到就替換為空。 |
| g/^\s*$/d | 含義同上 |
| %s/^[ |\t]*$// | % 表示在所有行搜索,第一個 s 表示替換,^ 表示行首,$ 表示行尾,\t 表示 TAB,中括號表達式 [ |\t] 表示空格或者 TAB,其實也可以寫成 [\s|\t]。表達式解釋:刪除包含任意個空格或者 TAB 的空行。 |
| g/^[ |\t]*$/d | 含義同上 |
| %s/linux/FreeBSD/ | 在整個文本的每一行檢索字符串 linux,將每行匹配到的第一個 linux 替換為 FreeBSD。注意:后面沒有加上 g 標記,針對的是每行第一次匹配到的源字符串。 |
| s/linux/FreeBSD/ | 不加 % ,則只作用于當前行,即只在光標所在行查找。沒有具體指定范圍,默認情況下只會替換當前行中第一次匹配到的源字符串,若要替換一行中所有匹配到的字符串,必須在命令后加 g 標記來修飾。 |
| %s/linux/FreeBSD/g | 將整個文檔中的字符串 linux 替換成 FreeBSD。% 表示在所有行查找匹配,g 表示更換一行中所有匹配到的源字符串,s 是替換的指令 |
| %s/linux/FreeBSD/gc | 將整個文檔中的字符串 linux 替換成 FreeBSD,且替換前詢問用戶。 |
| %s/\<four/4/g | 用 \< 來指定匹配單詞開頭。\<four 表示以 four 為單詞首。例如,fourfive 會被替換成 4five,而 fivefour 則不會改變,但是 fourty 則會變成 4ty ,顯然不是我們要的結果,怎么辦?使用這個 %s/\<four\>/4/g,\> 表示單詞尾,\<four\> 表示單詞首和單詞尾之間只有 four,即只查找 four 這個單詞,匹配到替換成 4。 |
| %s/abc\(.*\)xyz/xyz\1abc/g | 直接輸入 ( 會被 vim 認為屬于字符串的內容,其實不是,( 就是一個小括號,所以需要轉義,故書寫為 \(,) 同理要轉義。. 表示任意單個字符,就是* 表示任意數量,.* 表示任意數量的 .,而 . 代表任意一個字符,所以 .* 表示任意數量的任意字符(MySQL 中的通配符 * 就可以表達這個含義)。例如,a 可以匹配 .,ab 就不能匹配 .了,但是 .* 就可以匹配了,你可以理解為需要 2 個. 來匹配 ab,一個 . 匹配 a,另外一個. 匹配 b。所以最后 (.*) 表示任意數量的字符,而且這樣括號起來,可以被后面的表達式引用。例如,xyz\1abc,其中 \1 就是引用前面源字符串正則表達式中的第 1 個括號中的內容,那么就相當于 xyz\(.*\)abc。表達式解釋:把文本中的所有字符串 abc……xyz 替換為 xyz……abc。 |
| %s/\(abc\)\(.*\)\(xyz\)/\3\2\1/g | 含義同上,只是后面的替換字符串表達式倒序引用了前面的 3 個括號的內容,實際表達式就是 %s/\(abc\)\(.*\)\(xyz\)/\(xyz\)\(.*\)\(abc\)/g |
| %s/\(a.c\)\{3\}$/lwx/g | $ 表示行尾,這是個虛擬的概念。{3} 表示前面的字符串要出現 3 次,(a.c),小括號包裹的內容作為一個整體,所以小括號的內容整體要出現3次,. 表示任意一個字符,那么像這樣的 abcabcabc,adcafcagc 等都可以匹配,只要確保以 a 開頭,以 c 結尾,中間任意一個字符所組成的整體出現 3 次就可以了。表達式解釋:在文本的每行行尾查找匹配表達式 (a.c){3} 的字符串,查找到則替換成字符串 lwx。注意:在 vim 的正則表達式中要使用常規正則表達式的元字符(如小括號 (,大括號 { ),以正常使用常規正則表達式,必須在元字符前加反斜杠,否則 vim 會把很多元字符當成普通字符 |
(一)結合 copy 命令使用
[range] copy [address],將 range 的內容復制到 address 下方,copy 等價于 co,等價于 t。
| 6 t . | 把第6行復制到當前行下面 |
| 6 t | 同上,只是省略了 . |
| . t $ | 把當前行復制到文本末尾,注意這里的 $ 就不是行尾的含義了,而是整個文檔的最后一行的下方位置,其實也是虛擬的概念 |
| t $ | 同上 |
(二)結合 move 命令使用
[range] move [address],將 range 的內容移動到 address 下方,move 等價于 m
| . m $ | 將當前行移動到文本末尾 |
(三)結合 normal 命令使用
normal 表示“普通命令模式”。
[range] normal [command],對 range 范圍的文本內容執行“普通命令模式”下的命令 command
| % normal I // | 表示在整個文檔的行首插入 //,% 表示整個文檔,normal I,表示執行普通命令模式的指令 I,這個指令 I 就是在行首插入文本的意思,通常用于注釋代碼 |
| 2,4 normal A ++ | 在第2到第4行的末尾添加 ++,A 就是在行尾插入文本的意思 |
(四)匹配重復性模式
| /a* | 星號 * 規定在它前面的項可以出現任意次。因此 /a* 會匹配 a,aa,aaa 等等,并且也匹配空字符串,因為零次也包含在內。 |
| /ab* | 星號 * 僅僅應用于那個緊鄰在它前面的項。因此 /ab* 表示 b 可以重復任意次,所以會匹配 a,ab,abb,abbb 等等。 |
| /ab\+ | 要避免匹配空字串,使用 \+。這表示前面一項可以被匹配一次或多次,因此 /ab\+ 會匹配 ab,abb,abbb 等等。它不匹配后面沒有跟隨 b 的 a。 |
(五)指定重復次數
要匹配某一項的特定次數重復,使用 \{n,m} 這樣的形式。其中 n 和 m 都是數字。在它前面的那個項將被重復 n 到 m 次,包含 n 和 m。
| /ab\{3,5} | 表示緊鄰的 b 可以重復出現 3 次,4 次,5 次,所以可以匹配 abbb,abbbb 以及 abbbbb。 |
當 n 省略時,被默認為零。當 m 省略時,被默認為無限大。當 ,m 省略時,就表示重復正好 n 次,關于區間量詞的表達式如下表所示:
| \{,4} | 0,1,2,3 ,4 |
| \{3,} | 3,4,5,無限大,大于等于 3 |
| \{0,1} | 0 或 1,等同 \= |
| \{0,} | 0 或更多,等同 *,大于等于 0 |
| \{1,} | 1 或更多,等同 \+,大于等于 1 |
| \{3} | 3 |
(六)匹配可選項
| /folders\= | 要匹配一個可選項,用 \=。 /folders\= 表示緊鄰的 s 可有可無,也就是 0 個或者 1 個,所以匹配 folder 和 folders。 |
(七)多選一匹配模式/多選結構
\| 就是或的意思,表示兩者中的一個。
| /foo\|bar | 在一個查找模式中,“或”運算符是 \|。/foo\|bar 這個命令匹配 foo 或 bar。 |
(八)引用分組
pattern 中圓括號 () 包含的部分就是分組,后面可以使用 \n 進行引用,正常情況下,n 的取值范圍是 [1-9]。
源字符串:liaowenrettliaowenrtrdfgf
:s/\(liao\)\(wen\)/\2\1/g執行以上命令后,源字符串中的“liaowen”全部替換成“wenliao”。\1 引用 pattern 的第 1 個分組 (liao) 匹配到的字符串;\2 引用第 2 個分組 (wen) 匹配到的字符串。
(九)替換內容的特殊字符
1. & 符號
& 替換為模式的匹配,也即如果 pattern 匹配 helloworld,那么 & 就引用 helloworld。
示例 1:
:s/man/&,&,what/gcman 被替換成 man,man,what
示例 2:
:s/.*/{&}/g沒有指定 range,則僅在當前行匹配查找,所以上面的命令就是將當前行加了一個大括號 {}。
2. ~ 符號
~ 替換為上一次替換命令所用的 replacement。
示例 1:
:s/their/our/g # their --> our :s/his/~/g # his --> our :s/my/~/g # my --> our3. \u 和 \l
\u:把后一個字母轉成大寫。
\l:把后一個字母轉成小寫。
示例 1:
:s/\(what\)/\u\1/g\1 引起 pattern 的第 1 個分組所匹配到的字符串,上述命令就是 what,那么 \uwhat 就是 What,所以就是把 what 替換為 What。
示例 2:
:s/.*/\u&/g.* 表示匹配任意數量的任意字符(除了換行符);& 引用 pattern 匹配到的內容。所以上述的命令表示將當前行的第 1 個字符大寫,大哥,你還要確保當前行的第 1 個字符是英文字母才行。
:%s/.*/\u&/g以上的命令表示將整個文檔的每行的第 1 個字符轉成大寫。
示例 3:
:s/[a?zA?Z]\+/\u&/g將當前行匹配到的英文字符串的首個字母轉成大寫。
4. \U 和 \L
\U 表示后面的字符全部轉成大寫;\L 表示后面的字符全部轉成小寫。
示例 1:
:s/restore/\U&/g # restore --> RESTORE示例 2:
:s/ResTore/\L&/g # ResTore --> restore示例 3:
\U 和 \e 或 \E 組合使用,表示 \U 和 \E 之間的字符轉成大寫;\L 和 \e 或 \E 組合使用,表示 \L 和 \E 之間的字符轉成小寫。
:s/restore/re\Usto\ere/ # restore --> reSTOre(十)界定 pattern 的子集
元字符 \zs 標志著一個匹配的起始,而元字符 \ze 則用來界定匹配的結束。將二者相結合,可以讓我們先定義一個模式來匹配一個較大的文本范圍,然后再收窄匹配范圍。
我想要查找 Practical 后面的 Vim。
/Practical Vim使用上述的 pattern 文檔中所有出現 Practical Vim 的地方都會被搜索出來。一旦將查找模式改為:
/Practical \zsVim則只有單詞 Vim 會被高亮選中,而單詞 Practical 會被排除于匹配之外,但它仍是模式的一部分。
如此一來,只有前面緊跟著單詞 Practical 的 Vim 才會被真正匹配到,而其他前面不是 Practical 的 Vim 則不會被匹配。這與通過 /Vim 命令進行簡單查找的結果有很大不同。其實也可以使用“逆序肯定環視”來匹配。
總結
以上是生活随笔為你收集整理的vim 底行命令模式的正则表达式(匹配模式)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 绝地求生好听的名字大全106个
- 下一篇: 你比划我猜题目大全锦集104个