Vimscript 基本的正則表達(dá)式

2018-02-24 16:02 更新

Vim是一個文本編輯器,這意味著大量的Vimscript代碼將專注于處理文本。 Vim對正則表達(dá)式有著強(qiáng)大的支持,盡管一如既往地也有著一些坑。

把下面的文本打到緩沖區(qū)中:

max = 10

print "Starting"

for i in range(max):
    print "Counter:", i

print "Done"

這個就是我們將用來測試Vimscript的正則支持的文本。它恰好是Python代碼,但不要擔(dān)心你看不懂Python。 它只是一個例子。

我會假定你懂得基本的正則表達(dá)式。如果你不懂, 你應(yīng)該暫停閱讀本書并開始閱讀Zed Shaw的Learn Regex the Hard Way。 (譯注:暫無中文版,也可選擇別的書,或者just Google it) 在你看完后再繼續(xù)。

高亮

在開始之前,先花點(diǎn)時間講講搜索高亮,這樣我們可以讓匹配的內(nèi)容更明顯。

:set hlsearch incsearch

hlsearch讓Vim高亮文件中所有匹配項(xiàng),incsearch則令Vim在你正打著搜索內(nèi)容時就高亮下一個匹配項(xiàng)

搜索

移動你的光標(biāo)到文件頂部并執(zhí)行下面命令:

/print

當(dāng)你逐字母敲打時,Vim開始在第一行高亮它們。當(dāng)你按下回車來進(jìn)行搜索時,高亮_所有_的print, 同時移動你的光標(biāo)到下一處匹配。

現(xiàn)在嘗試執(zhí)行下面的命令:

:execute "normal! gg/print\<cr>"

這將移動到文件頂部并開始搜索print,帶我們到第一處匹配。 用的是我們前一章看過的:execute "normal! ..."語法。

要到達(dá)文件中的第二處匹配,你僅需在命令的結(jié)尾加一點(diǎn)別的。執(zhí)行這個命令:

:execute "normal! gg/print\<cr>n"

Vim將移動光標(biāo)到緩沖區(qū)中的第二個print(同時高亮所有匹配)。

讓我們嘗試從反方向開始。執(zhí)行這個命令:

:execute "normal! G?print\<cr>"

這次我們用G移動到文件結(jié)尾并用?來反向搜索。

所有的搜索命令應(yīng)該已經(jīng)爛熟于心 —— 我們在讓你習(xí)慣:execute "normal! ..."慣用法時已經(jīng)反復(fù)練習(xí)過, 因?yàn)樗屇阍赩imscript代碼中能夠做日常在Vim里做的事。

魔力(Magic)

/?命令能接受正則表達(dá)式,而不僅僅是普通字符。執(zhí)行下面命令:

:execute "normal! gg/for .+ in .+:\<cr>"

Vim抱怨說找不到模式!我告訴過你Vim支持正則搜索,所以為何如此?試試下面命令:

:execute "normal! gg/for .\\+ in .\\+:\<cr>"

這次Vim高亮"for"循環(huán),如我們一開始所指望的。在繼續(xù)閱讀之前,花一分鐘來想想為何如此。 記住execute接受一個字符串。

答案在此:我們需要這樣寫命令的原因有二:

  • 首先,execute接受一個字符串,在調(diào)用normal!命令時,雙反斜杠將轉(zhuǎn)換成單反斜杠。
  • Vim有四種不同的解析正則表達(dá)式的"模式"! 默認(rèn)模式下需要在+前加上一個反斜杠來讓它表示"一或多個之前的字符"而不是"一個字面意義上的加號"。

直接在Vim里執(zhí)行搜索,你很容易就注意到它們的不同,輸入下面的命令并按下回車:

/print .\+

現(xiàn)在你可以看到\+的魔力了。雙反斜杠僅僅在把模式作為字符串傳遞給execute時才需要。

字面量字符串

正如我們在字符串那一章提到的,Vim允許你使用單引號來定義可以直接傳遞字符的字面量字符串。 比如,字符串'a\nb'有四個字符長。

我們可以使用字面量字符串來避免頻繁敲打雙重反斜杠嗎? 先思考這個問題一兩分鐘,畢竟答案恐怕比你所認(rèn)為的要更復(fù)雜一些。

試試執(zhí)行下面的命令(注意這次的單引號和單反斜杠):

:execute 'normal! gg/for .\+ in .\+:\<cr>'

Vim帶你到文件的頂部卻不再移動到第一個匹配的地方。你猜對了嗎?

命令之所以不能工作,是因?yàn)槲覀冃枰J街械?code>\<cr>被轉(zhuǎn)義成回車,來啟動搜索。 因?yàn)槲覀冇玫氖亲置媪孔址?,它并不等價于平常在Vim里鍵入/for .\+ in .\+:\<cr>, 顯然這是無法工作的。

別怕,方法還是比困難多!不要忘了Vim允許字符串連接,所以可以將命令分割成容易理解的一小段。 執(zhí)行下面的命令:

:execute "normal! gg" . '/for .\+ in .\+:' . "\<cr>"

這種方法可以在傳遞給execute之前把三小段字符串連接起來, 而且我們可以為正則使用字面量字符串并為其他的使用一般的字符串。

更多的魔力(Very Magic)

你可能會好奇Vimscript的四種不同的正則解析模式和它們跟Python,Perl或Ruby中的正則表達(dá)式有何不同。 你可以閱讀它們的文檔,如果你樂意。不過如果你只想找到一種簡單科學(xué)的解決辦法,請繼續(xù)讀下去。

執(zhí)行下面的命令:

:execute "normal! gg" . '/\vfor .+ in .+:' . "\<cr>"

我們又一次把正則表達(dá)式放在單獨(dú)的字面量字符串里,而這次我們用\v來引導(dǎo)模式。 這將告訴Vim使用它的"very magic"正則解析模式,而該模式就跟其他語言的非常相似。

如果你以\v開始你的所有正則表達(dá)式,你就不用再糾結(jié)Vimscript另外三種瘋狂的正則模式了。

練習(xí)

認(rèn)真閱讀:help magic

閱讀:help pattern-overview來看看Vim支持的正則類型。在看到character classes時停下來。

閱讀:help match。嘗試手動執(zhí)行幾次:match Error /\v.../。

在你的~/.vimrc文件中加入使用match來高亮多余的空白為錯誤的映射。建議使用<leader>w。

加入另一個映射來清除匹配項(xiàng)(比如<leader>W)。

加入一個normal模式下的會在進(jìn)行搜索時自動插入\v的映射。 如果你卡在這個練習(xí)上,不要忘了Vim的映射是非常簡單的,你只需要告訴它把映射鍵轉(zhuǎn)換成哪些鍵。

在你的~/.vimrc文件中加入hlsearchincsearch選項(xiàng),隨你所欲地設(shè)置它。

閱讀:help nohlsearch。注意這是一個_命令_并且不是hlsearch的"off mode"。

在你的~/.vimrc文件中加入消除最后一次搜索的匹配項(xiàng)的高亮的映射。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號