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