1. 程式人生 > 其它 >vim 搜尋_Vim搜尋字元轉義與very magic搜尋模式

vim 搜尋_Vim搜尋字元轉義與very magic搜尋模式

技術標籤:vim 搜尋vim 查詢vim 查詢下一個xml中特殊含義的字元

假設需要在一個CSS樣式檔案中查詢所有的顏色程式碼,部分查詢目標如下所示。

a { color: #0000EE; }
body { color: #3c3c3c; }
strong { color: #000; }

為此,需要構造一個正則表示式,用於匹配 1個 # 字元以及緊隨其後的 3 個或 6 個十六進位制字元的目標串 (包括所有數字以及大寫或小寫的字母 A 到 F)。

1. 使用 magic 搜尋模式查詢

Vim預設設定下,/#([0-9a-fA-F]{6}|[0-9a-fA-F]{3}) 可以查詢到所有的目標顏色程式碼。

在上面的Vim正則表示式搜尋命令中,一共用到了 3 類括號:[]、() 和 {},而這 3 類括號都是正則表示式中的特殊字元 (有特殊含義的字元),若要匹配這些特殊字元,必須首先使 進行轉義。

正則表示式中,方括號 [] 用於定義待匹配的字元範圍,原括號 () 用於標記一個子表示式的開始和結束位置,而花括號 {} 用於指定匹配的長度。

對於Vim的正則表示式引擎來說,方括號 [] 預設具有特殊含義,不需要轉義;圓括號 () 預設會按原義匹配字元,因此需要使用 轉義,使其具有特殊含義;花括號 {} 也一樣需要使用 轉義,但與之對應的閉括號則不用,因為 Vim 會自動推測我們的意圖。這就是Vim的 magic 搜尋模式。

magic 搜尋模式會自動為某些額外的符號賦予特殊含義,例如 .*[ 等。magic 模式的初衷是想能在Vim中更容易地構造簡單的正則表示式,但它卻沒能為諸如 +?(){ 等符號賦予特殊含義,這些符號還必須經過轉義才具有特殊含義。

這種"半成品"性質的實現,使得在Vim下構建正則表示式搜尋模式,仍然十分麻煩,從上面查詢顏色程式碼的命令就可感受一二。

2. 使用 very magic 搜尋模式查詢

如上所述,magic 搜尋模式下,字元轉義的規則制定得比較混亂,容易混淆。

可以使用 v 開關啟用 very magic 搜尋模式,統一所有特殊符號的規則:

very magic 搜尋模式下,除下劃線 _
、大小寫字母以及數字 0 到 9 之 的所有字元 都具有特殊含義。

例如,使用 v 模式開關查詢上述匹配十六進位制顏色程式碼的正則表示式可簡化為:/v#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})

由於出現在起始位置的 v 開關,位於它後面的所有字元都具有特殊含義,用於轉義的反斜槓字元就可以去掉,正則表示式的可讀性更強了。

3. 使用 very nomagic 搜尋模式查詢

上面介紹的正則表示式中保留使用的特殊字元,在按模式查詢時用起來很方便,但如果想按原義查詢對應字元時,又該如何操作呢?

例如,如果想在下面的一段文字中查詢 a.k.a,使用Vim命令 /a.k.a. 並不能立馬精確地找到目標字串,因為符號 . 在正則表示式中具有特殊含義,它會匹配任意字元,因此單詞 backward 也會被搜尋到。

The N key searches backward...
...the v pattern switch (a.k.a. very magic search)...

當然,可以使用轉義的方法消除 . 字元的特殊含義,即 /a.k.a.

一種更簡單的使用方法是使用原義開關 V 啟用Vim的very nomagic 搜尋模式。

V 選項會使得其後的模式中 有且只有反斜槓 具有特殊意義,即消除了附加在 .* 以及 ? 等大多數字符上的特殊含義。

使用 V 原義開關精確搜尋 a.k.a 的命令可以簡化為:/Va.k.a.


介紹完上面提到的 Vim magic 搜尋模式、very magic 搜尋模式和 very nomagic 搜尋模式後,是不是反而會覺得規則太多,沒法快速地選擇所需要的模式。

其實,very magic 和 very nomagic 搜尋模式分別是Vim對正則表示式特殊字元的兩種極端處理方式。

對於Vim的正則表示式搜尋,一個通用的原則是:如果想按正則表示式查詢,就用模式開關 v,如果想按原義查詢文字,就用原義開關 V

4. 界定單詞的邊界

有些單詞,尤其是短詞,常常會出現在其他單詞內部,比如,the 就會在 these、they、their 等單詞中出現。如果想精確匹配 the 這個完整的單詞而不是其他詞的組成部分,可以使用單詞定界符。

在 very magic 搜尋模式下,用 <> 符號表示 單詞定界符

因此,如果將查詢命令改為 /v<the>,就會精確查詢到 the 這個單詞。

其實,用單詞定界符構造精確查詢模式的方式早就已經介紹並使用過了。在Vim搜尋命令使用方法和技巧一文中已經介紹過,Vim普通模式下使用 *# 可以用於正向或反向精確查詢當前游標所在單詞。

當然,在 magic、以及 very nomagic 搜尋模式下,<> 都必須使用 進行轉義才能將其作為單詞定界符,而如果想在 very magic 搜尋模式下匹配尖括號本身的話,也必須將其轉義才有單詞定界符的含義。如果你還沒理解這兩句話,建議再細讀下上面關於magic、以及 very nomagic 搜尋模式的規則介紹。

5. 界定匹配的邊界

在使用Vim的某些場景下,可能想指定一個範圍較廣的模式,但只對匹配結果的一部分內容感興趣。

應該明確,當我們談論一個模式的時候,指的是在查詢域輸入的正則表示式 (或按原義匹配的文字);而匹配,是指在文件中被高亮顯示的文字內容。

一個 匹配的邊界通常對應一個 模式的起始與結尾。但可以使用元字元 zsze匹配進行裁剪,使其成為這個完整 模式的一個子集。

元字元 zs 標誌著一個匹配的起始,而元字元 ze 則用來界定匹配的結束。將二者相結合,可以讓我們先定義一個模式來匹配一個較大的文字範圍,然後再收窄匹配範圍。例如:

如果使用Vim查詢命令 /Practical Vim,則文件中所有出現 Practical Vim 的地方都會被搜尋出來。一旦將查詢模式改為 /Practical zsVim,則只有單詞 Vim 會被高亮選中,而單詞 Practical 會被排除於匹配之外,但它仍是模式的一部分。

如此一來,只有緊跟著單詞 Practical 的 Vim 才會被查詢到,而其他前面不是 Practical 的 Vim 則不會被匹配。這與通過 /Vim 命令進行簡單查詢的結果有很大不同。

ea7c0463cd7743ec4422d0c7c4dba5dc.gif