如何將一串十進(jìn)制數(shù)字轉(zhuǎn)換為 16 進(jìn)制數(shù)字,使用 VIM 完成轉(zhuǎn)換的最簡(jiǎn)單方法如下: :%s//d/+//=printf(%X, submatch(0))/g 這條命令的原理是,把一串?dāng)?shù)字,用 printf() 函數(shù)的輸出替換掉, printf() 函數(shù)輸出的正是這串?dāng)?shù)字的 16 進(jìn)制形式。 分解如下: %s 在
如何將一串十進(jìn)制數(shù)字轉(zhuǎn)換為16進(jìn)制數(shù)字,使用VIM完成轉(zhuǎn)換的最簡(jiǎn)單方法如下:
:%s//d/+//=printf("%X", submatch(0))/g
這條命令的原理是,把一串?dāng)?shù)字,用printf()函數(shù)的輸出替換掉,printf()函數(shù)輸出的正是這串?dāng)?shù)字的16進(jìn)制形式。
分解如下:
%s 在整個(gè)文件中替換 (:help :s )
/d/+ 匹配一個(gè)或多個(gè)數(shù)字 (:help //d :help //+ )
/= 使用表達(dá)式的結(jié)果進(jìn)行替換 (:help //w )
printf 按指定格式輸出 (:help printf() )
submatch() 返回:s命令中的指定匹配字符串 (:help submatch() )
g 替換行內(nèi)所有出現(xiàn)的匹配 (:help :s_flags)
看來(lái),替換命令的巧妙使用可以完成很多意想不到的功能!
下面這個(gè)技巧是在VIM郵件列表中看到的,非常實(shí)用。
這里以編寫C語(yǔ)言程序?yàn)槔?假設(shè),我們最終想完成的代碼如下:
#define BIT_MASK_1 (1 << 0)
#define BIT_MASK_2 (1 << 1)
#define BIT_MASK_3 (1 << 2)
#define BIT_MASK_4 (1 << 3)
#define BIT_MASK_5 (1 << 4)
#define BIT_MASK_6 (1 << 5)
#define BIT_MASK_7 (1 << 6)
#define BIT_MASK_8 (1 << 7)
#define BIT_MASK_9 (1 << 8)
#define BIT_MASK_10 (1 << 9)
#define BIT_MASK_11 (1 << 10)
#define BIT_MASK_12 (1 << 11)
#define BIT_MASK_13 (1 << 12)
#define BIT_MASK_14 (1 << 13)
#define BIT_MASK_15 (1 << 14)
#define BIT_MASK_16 (1 << 15)
#define BIT_MASK_17 (1 << 16)
#define BIT_MASK_18 (1 << 17)
#define BIT_MASK_19 (1 << 18)
#define BIT_MASK_20 (1 << 19)
#define BIT_MASK_21 (1 << 20)
#define BIT_MASK_22 (1 << 21)
#define BIT_MASK_23 (1 << 22)
#define BIT_MASK_24 (1 << 23)
#define BIT_MASK_25 (1 << 24)
#define BIT_MASK_26 (1 << 25)
#define BIT_MASK_27 (1 << 26)
#define BIT_MASK_28 (1 << 27)
#define BIT_MASK_29 (1 << 28)
#define BIT_MASK_30 (1 << 29)
#define BIT_MASK_31 (1 << 30)
#define BIT_MASK_32 (1 << 31)
我們不需要一行一行的去寫,只需要先寫好第一行,如下:
#define BIT_MASK_1 (1 << 0)
然后,我們回到Normal模式,在這一行上輸入“Y31p",拷貝此行,然后粘貼31次。這樣,我們得到總共32行上面的內(nèi)容。
現(xiàn)在使用"V31j"命令選中這32行,然后使用兩次替換命令:
:'<,'>s/BIT_MASK_/zs/d*/ze//=line(".") - line("'<") + 1
:'<,'>s//zs/d*/ze)$//=line(".")-line("'<")
這樣,我們就得到了我們想要的結(jié)果。
這種方式還可以用于數(shù)組下標(biāo)的自動(dòng)增加,以及文本的章節(jié)自動(dòng)編號(hào)等功能。只要你能夠用正則表達(dá)式準(zhǔn)確的定位出你想要自動(dòng)編號(hào)的的數(shù)字,那么就可以使用這種方法來(lái)自動(dòng)編號(hào)。
以第一條命令為例,第二條命令和第一條命令類似:
:'<,'>s/BIT_MASK_/zs/d*/ze//=line(".") - line("'<") + 1
這條命令在我們選中的區(qū)域內(nèi)進(jìn)行替換,查找以“BIT_MASK_”開頭,后面跟任意多個(gè)數(shù)字的字符串,并把匹配位置放在數(shù)字上,然后使用后面表達(dá)式計(jì)算出來(lái)的數(shù)字替換這些匹配的數(shù)字。
下面是這條命令中每個(gè)元素的含義:
'<,'> 我們所選中的區(qū)域 (:help '<,:help '> )
s 在選中的區(qū)域中進(jìn)行替換 (:help :s )
/zs 指明匹配由此開始 (:help //zs )
/d* 查找任意位數(shù)的數(shù)字 (:help //d )
/ze 指明匹配到此為止 (:help //ze )
/= 指明后面是一個(gè)表達(dá)式 (:help :s/= )
line(".") 當(dāng)前光標(biāo)所在行的行號(hào) (:help line() )
line("'<") 我們所選區(qū)域中第一行的行號(hào) (:help line() )
“'<”和“'>”是我們使用了“v”,“V”命令選中一個(gè)visual區(qū)域后,VIM設(shè)置的標(biāo)記,分別用來(lái)標(biāo)識(shí)visual區(qū)域的開始和結(jié)束。
“BIT_MASK_/zs/d*/ze”是一個(gè)正則表達(dá)式,用來(lái)查找以“BIT_MASK_”開頭,后面跟任意多個(gè)數(shù)字的字符串。其中“/zs”、“/ze”用來(lái)指定匹配的開始和結(jié)束位置,因?yàn)槲覀冎淮蛩闾鎿Q“BIT_MASK_0”中的數(shù)字,所以在查找時(shí)只把匹配區(qū)域置在數(shù)字上。
由于我們的替換操作要把不同行的數(shù)字替換成不同的值,所以在這里需要使用一個(gè)表達(dá)式來(lái)計(jì)算出替換后的值。當(dāng)“:s”命令的替換字符串是以“/=”開頭時(shí),表明使用一個(gè)表達(dá)式計(jì)算的結(jié)果進(jìn)行替換。我們這里的表達(dá)式就是“line(".") - line("'<") + 1”,其中“line()”函數(shù)用來(lái)獲得行號(hào),它可以獲得當(dāng)前行的行號(hào),以及指定的標(biāo)記(mark)所在的行號(hào)。“line(".")”用來(lái)獲得當(dāng)前光標(biāo)所在行的行號(hào),“line("'<")”則用來(lái)獲得“'<”標(biāo)記所在行的行號(hào)。這兩個(gè)行號(hào)的差加上1就是我們想替換的值。
在上面的例子中,我們使用VIM的替換功能,實(shí)現(xiàn)高效的代碼編寫。現(xiàn)在介紹另外一種方法,實(shí)現(xiàn)相同的功能。
我們先看例子:
UniqueID2 = lview.focusedItem.subItems.opIndex(0).text;
Parent = lview.focusedItem.subItems.opIndex(0).text;
Children = lview.focusedItem.subItems.opIndex(0).text;
login = lview.focusedItem.subItems.opIndex(1).text;
txtCust.text = lview.focusedItem.subItems.opIndex(2).text;
txtProj.text = lview.focusedItem.subItems.opIndex(3).text;
txtbDate.text = lview.focusedItem.subItems.opIndex(4).text;
txtdDate.text = lview.focusedItem.subItems.opIndex(5).text;
txteDate.text = lview.focusedItem.subItems.opIndex(6).text;
txtPM.text = lview.focusedItem.subItems.opIndex(7).text;
txtLang.text = lview.focusedItem.subItems.opIndex(8).text;
txtVendor.text = lview.focusedItem.subItems.opIndex(9).text;
txtInvoice.text = lview.focusedItem.subItems.opIndex(10).text;
txtPMFund.text = lview.focusedItem.subItems.opIndex(11).text;
txtProjFund.text= lview.focusedItem.subItems.opIndex(12).text;
txtA_No.text = lview.focusedItem.subItems.opIndex(13).text;
txtNotes.text = lview.focusedItem.subItems.opIndex(14).text;
txtStatus.text = lview.focusedItem.subItems.opIndex(15).text;
我們要把上面代碼中括號(hào)中的數(shù)字,替換成由0開始的一個(gè)順序遞增序列,例如:
UniqueID2 = lview.focusedItem.subItems.opIndex(0).text;
Parent = lview.focusedItem.subItems.opIndex(1).text;
Children = lview.focusedItem.subItems.opIndex(2).text;
……
實(shí)現(xiàn)以上需求,除了用前面介紹的方法外,還可以用下面的命令:
:let n=0 | g/opIndex(/zs/d/+/s///=n/|let n+=1
下面簡(jiǎn)單講解一下這條命令各個(gè)組成元素:
let 為變量賦值 (:help let )
| 用來(lái)分隔不同的命令 (:help :bar )
g 在匹配后面模式的行中執(zhí)行指定的ex命令 (:help :g )
/zs 指明匹配由此開始 (:help //zs )
/d/+ 查找1個(gè)或多個(gè)數(shù)字 (:help //d )
s 對(duì)匹配模式進(jìn)行替換 (:help :s )
/= 指明后面是一個(gè)表達(dá)式 (:help :s/= )
所以,這條命令的執(zhí)行過(guò)程為:
1. 給變量n賦值為0;
2. 查找模式” opIndex(/zs/d/+”,使用變量n的值替換匹配的模式字符串;
3. 給變量n加1;
需要說(shuō)明一下”|”,它用來(lái)分隔不同的命令。
另外,在substitute命令中,如果省略匹配模式字符串,它會(huì)使用之前定義的匹配模式字符串,在本例中就是由”global”命令定義的”opIndex(/zs/d/+”。
除了上面介紹的方法外,還有一個(gè)VIM插件專門實(shí)現(xiàn)數(shù)字、日期等的增、減,可以在下面的網(wǎng)址下載此插件:
http://vim.sourceforge.net/scripts/script.php?script_id=670
或
http://mysite.verizon.net/astronaut/vim/index.html#VISINCR
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com