模式
Nvim :help
頁面,使用 tree-sitter-vimdoc 解析器,從 來源產生。
模式與搜尋指令
/ /{pattern}[/]<CR> 向前搜尋第 [count] 次出現的
{pattern}
不包含。
/{pattern}/{offset}<CR> 向前搜尋第 [count] 次出現的
{pattern}
並上下移動
{offset} 行。
行模式。
? ?{pattern}[?]<CR> 向後搜尋第 [count] 次出現的
{pattern}
不包含。
?{pattern}?{offset}<CR> 向後搜尋第 [count] 次出現的
{pattern}
並上下移動
{offset} 行。
行模式。
n n 重複執行最後一次 "/" 或 "?" [count] 次。如果游標沒有移動,則搜尋會以 count + 1 的次數重複。
last-pattern
# # 與 "*" 相同,但向後搜尋。井號 (字元 163) 也有效。如果 "#" 鍵的功能是退格,請在啟動 Vim 前嘗試使用 "stty erase
<BS>
" (
<BS>
是
CTRL-H
或真正的退格鍵)。
v_#-default
{Visual}
# 在視覺模式中,向後搜尋目前選取的範圍。
預設對應
gstar g* 與 "*" 類似,但不將 "\<" 和 "\>" 放在單字周圍。這使得搜尋也可以找到非完整單字的匹配項。
g# g# 與 "#" 類似,但不將 "\<" 和 "\>" 放在單字周圍。這使得搜尋也可以找到非完整單字的匹配項。
gd gd 跳到局部宣告。當游標位於局部變數上時,此指令會跳到其宣告處。此指令最初設計用於 C 程式碼,在其他語言中可能無法正常運作。首先,Vim 會搜尋目前函式的開頭,就像 "[[ " 一樣。如果找不到,搜尋會在第 1 行停止。如果找到,Vim 會往回搜尋,直到找到空白行。從這個位置開始,Vim 會搜尋游標下的關鍵字,如同使用 "*",但會忽略看起來像註解的行 (請參閱
'comments' 選項)。請注意,這並不能保證一定能正常運作,Vim 並不會真正檢查語法,它只會搜尋與關鍵字匹配的內容。如果還需要搜尋包含的檔案,請使用
include-search 中列出的指令。在此指令執行後,
n 會向前搜尋下一個匹配項 (而不是向後)。
gD gD 跳到全域宣告。當游標位於檔案中定義的全域變數時,此指令會跳到其宣告處。此指令的運作方式與 "gd" 類似,不同之處在於搜尋關鍵字始終從第 1 行開始。
1gd 1gd 與 "gd" 類似,但會忽略游標位置之前結束的 {} 區塊中的匹配項。
1gD 1gD 與 "gD" 類似,但會忽略游標位置之前結束的 {} 區塊中的匹配項。
CTRL-C CTRL-C 中斷目前的 (搜尋) 指令。在普通模式中,任何待處理的指令都會被中止。
輸入搜尋模式時,如果
'incsearch' 選項已開啟,則會顯示目前的匹配項。請記住,您仍然必須使用
<CR>
完成搜尋指令,才能將游標實際定位到顯示的匹配項。或者使用
<Esc>
來放棄搜尋。
當
'shortmess' 不包含 "S" 旗標時,Vim 會自動顯示游標所在的索引。它看起來會像這樣
[1/5] Cursor is on first of 5 matches.
[1/>99] Cursor is on first of more than 99 matches.
[>99/>99] Cursor is after 99 match of more than 99 matches.
[?/??] Unknown how many matches exists, generating the
statistics was aborted because of search timeout.
注意:次數不考慮偏移。
當找不到匹配項時,您會收到錯誤訊息:
E486 找不到模式。請注意,對於
:global
指令,您會收到一般訊息「找不到模式」,以符合 Vi 相容性。對於
:s 指令,可以使用 "e" 旗標來避免錯誤訊息
:s_flags。
偏移會給出相對於找到的匹配項的游標位置: [num] 游標位置向下 [num] 行,在第 1 欄 +[num] 游標位置向下 [num] 行,在第 1 欄 -[num] 游標位置向上 [num] 行,在第 1 欄 e[+num] 游標位置位於匹配項結尾右側 [num] 個字元 e[-num] 游標位置位於匹配項結尾左側 [num] 個字元 s[+num] 游標位置位於匹配項開頭右側 [num] 個字元 s[-num] 游標位置位於匹配項開頭左側 [num] 個字元 b[+num] 與上面的 s[+num] 相同 (助記符:begin) b[-num] 與上面的 s[-num] 相同 (助記符:begin) ;{pattern} 執行另一個搜尋,請參閱
//;
如果給定 '-' 或 '+' 但省略了 [num],則會使用計數 1。當偏移包含 'e' 時,搜尋會變成包含性的 (游標所在的字元會包含在操作中)。
範例
模式 游標位置
/test/+1 "test" 下方一行,在第 1 欄 /test/e 在 "test" 的最後一個 t 上 /test/s+2 在 "test" 的 's' 上 /test/b-3 在 "test" 前的 3 個字元
如果其中一個指令在運算子後使用,則游標位置在搜尋前後的字元之間會受到影響。但是,如果給定行偏移,則會影響兩個游標位置之間的所有行。
以下是如何搜尋具有模式的匹配項,並將匹配項變更為另一個單字的範例
/foo<CR> find "foo"
c//e<CR> change until end of match
bar<Esc> type replacement
//<CR> go to start of next match
c//e<CR> change until end of match
beep<Esc> type another replacement
etc.
//; E386 一個非常特殊的偏移是 ';' 後面接著另一個搜尋指令。例如
/test 1/;/test
/test.*/+1;?ing?
第一個會先找到下一個 "test 1",然後在該位置之後找到第一個 "test"。
這就像接連執行兩個搜尋指令,不同之處在於
它可以作為運算子後的單一移動指令使用。
後續 "n" 或 "N" 指令的方向來自第一個搜尋指令。
發生錯誤時,游標完全不會移動。
last-pattern 會記住最後使用的模式和偏移。它們可以用來重複搜尋,可以採用另一個方向或另一個次數。請注意,會記住兩個模式:一個用於「正常」搜尋指令,另一個用於替換指令 ":s"。每次給定空模式時,都會使用先前使用的模式。但是,如果沒有先前的搜尋指令,則會盡可能使用先前的替換模式。
若要清除最後使用的搜尋模式
:let @/ = ""
這不會將模式設定為空字串,因為空字串會比對所有位置。模式會真正被清除,就像啟動 Vim 時一樣。
搜尋通常會跳過不會移動游標的匹配項。下一個匹配項是在下一個字元找到還是跳過匹配項後找到,取決於
'cpoptions' 中的 'c' 旗標。請參閱
cpo-c。使用 'c' 旗標:"/..." 前進 1 到 3 個字元 未使用 'c' 旗標:"/..." 前進 1 個字元 'c' 旗標的不可預測性是由於從第一欄開始搜尋,跳過匹配項直到找到游標位置之後的匹配項所導致。
向後搜尋時,會從該行的開頭開始搜尋,並使用
'cpoptions' 中的 'c' 旗標,如上所述。然後使用游標位置之前的最後一個匹配項。
在 Vi 中,當搜尋標籤時,":tag" 命令會設定最後的搜尋模式。在 Vim 中則不會這樣,除非
'cpoptions' 中存在 't' 旗標,否則會記住先前的搜尋模式。搜尋模式總是會被放入搜尋歷史記錄中。
如果
'wrapscan' 選項啟用(預設為啟用),搜尋會在緩衝區的結尾處環繞。如果未設定
'wrapscan',則向後搜尋會在開頭停止,而向前搜尋會在緩衝區的結尾停止。如果設定了
'wrapscan' 且找不到模式,則會顯示錯誤訊息「pattern not found」,且游標不會移動。如果未設定
'wrapscan',則向前搜尋時訊息會變成「search hit BOTTOM without match」,而向後搜尋時則會變成「search hit TOP without match」。如果設定了 wrapscan 且搜尋在檔案結尾處環繞,則向後搜尋時會顯示訊息「search hit TOP, continuing at BOTTOM」,向前搜尋時則會顯示訊息「search hit BOTTOM, continuing at TOP」。可以透過在
'shortmess' 選項中設定 's' 旗標來關閉此訊息。此訊息使用高亮顯示方法 'w'(預設:突出顯示)。
搜尋範圍 您可以透過包含 \%>l 項目來限制搜尋命令 "/" 的行數範圍。例如,要在第 199 行以下和第 300 行以上比對單字「limit」
/\%>199l\%<300llimit
另請參閱
/\%>l。
另一種方式是使用帶有 'c' 旗標的 ":substitute" 命令。範例
:.,300s/Pattern//gc
此命令會從游標位置開始搜尋直到第 300 行,尋找「Pattern」。在比對到時,系統會要求您輸入一個字元。輸入 'q' 可在此比對停止,輸入 'n' 可尋找下一個比對。
"*"、"#"、"g*" 和 "g#" 命令會依此順序尋找游標附近的單字,找到的第一個會被使用
目前游標下的關鍵字。
同一行中游標右邊的第一個關鍵字。
目前游標下的 WORD。
同一行中游標右邊的第一個 WORD。關鍵字可能只包含字母和
'iskeyword' 中的字元。WORD 可能包含任何非空白字元(
<Tab>
和/或
<Space>
)。請注意,如果您用十根手指打字,這些字元很容易記住:"#" 在您的左手中指下方(向左和向上搜尋),而 "*" 在您的右手中指下方(向右和向下搜尋)。(這取決於您的鍵盤配置)。
E956 在極少數情況下,會遞迴使用正規表示式。當執行模式花費很長時間,以及在檢查通道上的訊息時,會調用也使用模式的回呼或觸發自動命令時,可能會發生這種情況。在大多數情況下,這應該沒問題,但是如果在再次使用某個模式時,該模式正在使用中,則會失敗。通常,這表示該模式有問題。
/bar /\bar /pattern 1. 模式是一個或多個分支,以 "\|" 分隔。它比對符合其中一個分支的任何內容。範例:「foo\|beep」比對「foo」和「beep」。如果有多個分支比對,則會使用第一個分支。
pattern ::= branch 或 branch \| branch 或 branch \| branch \| branch 等。
/branch /\& 2. 分支是一個或多個串聯,以 "\&" 分隔。它比對最後一個串聯,但前提是所有先前的串聯也在同一位置比對。範例:「foobeep\&...」比對「foobeep」中的「foo」。「.*Peter\&.*Bob」比對包含「Peter」和「Bob」的行。
branch ::= concat 或 concat \& concat 或 concat \& concat \& concat 等。
/concat 3. 串聯是一個或多個片段的串聯。它比對第一個片段的比對,然後是第二個片段的比對,依此類推。範例:「f[0-9]b」,先比對「f」,然後比對一個數字,最後比對「b」。
concat ::= piece 或 piece piece 或 piece piece piece 等。
/piece 4. 片段是一個原子,後面可能跟著一個 multi,表示原子可以比對的次數。範例:「a*」比對任何「a」字元的序列:「」、「a」、「aa」等等。請參閱
/multi。
piece ::= atom 或 atom multi
/atom 5. 原子可以是長串項目之一。許多原子比對文字中的一個字元。它通常是一個普通字元或一個字元類別。括號可以用來將模式變成原子。「\z(\)」結構僅用於語法高亮顯示。
/\%#= two-engines NFA Vim 包括兩個正規表示式引擎:1. 一個舊的、回溯引擎,支援所有功能。2. 一個新的 NFA 引擎,在某些模式下運作速度更快,在某些模式下可能會比較慢。
E1281Vim 會自動為您選擇正確的引擎。但是,如果您遇到問題或想特別選擇一個引擎,您可以在模式前面加上以下其中一個:
\%#=0 強制自動選擇。僅當
'regexpengine' 已設定為非零值時才會生效。\%#=1 強制使用舊引擎。\%#=2 強制使用 NFA 引擎。
模式中的某些字元,例如字母,會被視為字面意義。它們會與文字中完全相同的字元比對。但是,如果前面加上反斜線,這些字元可能會獲得特殊含義。例如,「a」比對字母「a」,而「\a」比對任何字母字元。
其他字元在沒有反斜線的情況下具有特殊含義。它們需要在前面加上反斜線才能以字面方式比對。例如,「.」比對任何字元,而「\.」比對點。
使用「\V」表示它之後只有反斜線和終止字元(通常為 / 或 ?)具有特殊含義:「非常非魔術」。
範例
之後:\v \m \M \V 比對
'magic' 'nomagic' a a a a 字面 'a' \a \a \a \a 任何字母字元 . . \. \. 任何字元 \. \. . . 字面點 $ $ $ \$ 行尾 * * \* \* 前一個原子的任何數量 ~ ~ \~ \~ 最新的替代字串 () \(\) \(\) \(\) 群組作為原子 | \| \| \| 無:分隔替代方案 \\ \\ \\ \\ 字面反斜線 \{ { { { 字面大括號
如果您願意,您可以透過將 "\m" 或 "\M" 放在模式的開頭,使模式不受
'magic' 選項的設定與否的影響。
multi
/star * \* 0 個或更多,盡可能多
/\+ \+ \+ 1 個或更多,盡可能多
/\= \= \= 0 個或 1 個,盡可能多
/\? \? \? 0 個或 1 個,盡可能多
/\{ \{n,m} \{n,m} n 到 m 個,盡可能多 \{n} \{n} 剛好 n 個 \{n,} \{n,} 至少 n 個,盡可能多 \{,m} \{,m} 0 到 m 個,盡可能多 \{\} \{\} 0 個或更多,盡可能多(與 "*" 相同)
/\{- \{-n,m} \{-n,m} n 到 m 個,盡可能少 \{-n} \{-n} 剛好 n 個 \{-n,} \{-n,} 至少 n 個,盡可能少 \{-,m} \{-,m} 0 到 m 個,盡可能少 \{-} \{-} 0 個或更多,盡可能少
字元類別:
/character-classes
magic nomagic 比對
/\i \i \i 識別字元 (請參閱
'isident' 選項)
/\I \I \I 類似 "\i",但不包含數字
/\k \k \k 關鍵字字元 (請參閱
'iskeyword' 選項)
/\K \K \K 類似 "\k",但不包含數字
/\f \f \f 檔案名稱字元 (請參閱
'isfname' 選項)
/\F \F \F 類似 "\f",但不包含數字
/\p \p \p 可列印字元 (請參閱
'isprint' 選項)
/\P \P \P 類似 "\p",但不包含數字
/\s \s \s 空白字元:
<Space>
和
<Tab>
/\S \S \S 非空白字元,與 \s 相反
/\d \d \d 數字:[0-9]
/\D \D \D 非數字:[^0-9]
/\x \x \x 十六進位數字:[0-9A-Fa-f]
/\X \X \X 非十六進位數字:[^0-9A-Fa-f]
/\o \o \o 八進位數字:[0-7]
/\O \O \O 非八進位數字:[^0-7]
/\w \w \w 單字字元:[0-9A-Za-z_]
/\W \W \W 非單字字元:[^0-9A-Za-z_]
/\h \h \h 單字開頭字元:[A-Za-z_]
/\H \H \H 非單字開頭字元:[^A-Za-z_]
/\a \a \a 字母字元:[A-Za-z]
/\A \A \A 非字母字元:[^A-Za-z]
/\l \l \l 小寫字元:[a-z]
/\L \L \L 非小寫字元:[^a-z]
/\u \u \u 大寫字元:[A-Z]
/\U \U \U 非大寫字元:[^A-Z]
/\_ \_x \_x 其中 x 是以上任何字元:包含行尾的字元類別 (字元類別結束)
x x 沒有特殊含義的字元比對自己
/[] [] \[] 在 [] 內指定的任何字元
/\%[] \%[] \%[] 一系列選擇性比對的原子
/\%d \%d \%d 比對指定的十進位字元 (例如 \%d123)
/\%x \%x \%x 比對指定的十六進位字元 (例如 \%x2a)
/\%o \%o \%o 比對指定的八進位字元 (例如 \%o040)
/\%u \%u \%u 比對指定的多位元組字元 (例如 \%u20ac)
/\%U \%U \%U 比對指定的大型多位元組字元 (例如 \%U12345678)
/\%C \%C \%C 比對任何組合字元
比對範例
\<\I\i* 或 \<\h\w* \<[a-zA-Z_][a-zA-Z0-9_]* 一個識別字 (例如,在 C 程式中)。
\(\.$\|\. \) 一個句點後面接著 <EOL>
或一個空格。
[.!?][])"']*\($\|[ ]\) 一個搜尋模式,尋找句子的結尾,其定義幾乎與 ")" 命令相同。
cat\Z "cat" 和 "càt" ("a" 後面接著 0x0300) 皆可比對。不會比對 "càt" (字元 0x00e0),即使看起來可能相同。
一個原子後面可以接一個指示,說明該原子可以比對的次數和方式。這稱為多重。請參閱
/multi 以取得概述。
/star /\star * (當未設定
'magic' 時使用 \*) 比對前一個原子 0 次或更多次,盡可能比對多次。
a* a\* "", "a", "aa", "aaa" 等等 .* \.\* 任何內容,也包含空字串,不包含行尾 \_.* \_.\* 緩衝區中直到結尾的所有內容 \_.*END \_.\*END 緩衝區中直到最後一個 "END" 的所有內容,包含 "END"
例外狀況:當 "*" 用於樣式的開頭或緊接在 "^" 之後時,它會比對星號字元。
請注意,重複使用 "\_." 可能會比對大量文字並耗費很長時間。例如,"\_.*END" 會比對從目前位置到檔案中最後一次出現 "END" 的所有文字。由於 "*" 會盡可能比對多次,因此這會先跳過所有行直到檔案結尾,然後嘗試比對 "END",一次回溯一個字元。
/\+ \+ 比對前一個原子 1 次或更多次,盡可能比對多次。
比對範例
^.\+$ 任何非空行 \s\+ 至少一個字元的空白
/\= \= 比對前一個原子 0 次或 1 次,盡可能比對多次。
比對範例
foo\= "fo" 和 "foo"
/\? \? 與 \= 相同。當使用 "?" 命令向後搜尋時無法使用。
/\{ E60 E554 E870 \{n,m} 比對前一個原子 n 到 m 次,盡可能比對多次 \{n} 比對前一個原子 n 次 \{n,} 比對前一個原子至少 n 次,盡可能比對多次 \{,m} 比對前一個原子 0 到 m 次,盡可能比對多次 \{\} 比對前一個原子 0 次或更多次,盡可能比對多次 (類似 "*")
/\{-\{-n,m} 比對前一個原子 n 到 m 次,盡可能比對最少次 \{-n} 比對前一個原子 n 次 \{-n,} 比對前一個原子至少 n 次,盡可能比對最少次 \{-,m} 比對前一個原子 0 到 m 次,盡可能比對最少次 \{-} 比對前一個原子 0 次或更多次,盡可能比對最少次
n 和 m 是正十進位數字或零
non-greedy如果 "-" 緊接在 "{" 之後出現,則會使用最短比對優先演算法 (請參閱下方範例)。特別是,"\{-" 與 "*" 相同,但使用最短比對優先演算法。但是:較早開始的比對優先於較短的比對:"a\{-}b" 會比對 "xaaab" 中的 "aaab"。
比對範例
ab\{2,3}c "abbc" 或 "abbbc" a\{5} "aaaaa" ab\{2,}c "abbc"、"abbbc"、"abbbbc" 等等 ab\{,3}c "ac"、"abc"、"abbc" 或 "abbbc" a[bc]\{3}d "abbbd"、"abbcd"、"acbcd"、"acccd" 等等 a\(bc\)\{1,2}d "abcd" 或 "abcbcd" a[bc]\{-}[cd] "abcd" 中的 "abc" a[bc]*[cd] "abcd" 中的 "abcd"
} 可以選擇性地以反斜線作為前綴:\{n,m\}。
/\@= \@= 以零寬度比對前一個原子。類似 Perl 中的 "(?=pattern)"。
比對範例
foo\(bar\)\@= "foobar" 中的 "foo" foo\(bar\)\@=foo 沒有任何內容
/zero-width當使用 "\@=" (或 "^"、"$"、"\<"、"\>") 時,比對中不包含任何字元。這些項目僅用於檢查是否可以進行比對。這可能會很棘手,因為與後續項目的比對將在相同的位置完成。上面的最後一個範例將不會比對 "foobarfoo",因為它嘗試在 "bar" 比對到的相同位置比對 "foo"。
請注意,使用 "\&" 的效果與使用 "\@=" 相同:"foo\&.." 與 "\(foo\)\@=.." 相同。但是使用 "\&" 更容易,您不需要括號。
/\@! \@! 如果前一個原子在目前位置 *不* 比對,則以零寬度比對。
/zero-width 類似 Perl 中的 "(?!pattern)"。
比對範例
foo\(bar\)\@! 任何不是後接 "bar" 的 "foo" a.\{-}p\@! "a"、"ap"、"app"、"appp" 等等,並非緊接在 "p" 之後 if \(\(then\)\@!.\)*$ "if " 並非後接 "then"
使用 "\@!" 很棘手,因為有很多地方模式無法比對。"a.*p\@!" 會比對從 "a" 到行尾的內容,因為 ".*" 可以比對行中的所有字元,而 "p" 不會在行尾比對。"a.\{-}p\@!" 會比對任何 "a"、"ap"、"app" 等等,這些字元並非後接 "p",因為 "." 可以比對 "p",而且 "p\@!" 在之後不會比對。
您無法使用 "\@!" 來尋找比對位置之前的非比對:在 "foobar" 中,"\(foo\)\@!bar" 會比對 "bar",因為在 "bar" 比對的位置,"foo" 不會比對。若要避免比對 "foobar",您可以使用 "\(foo\)\@!...bar",但這不會比對行開頭的 bar。使用 "\(foo\)\@<!bar"。
有用的範例:尋找不包含 "bar" 的行中的 "foo"
/^\%(.*bar\)\@!.*\zsfoo
此模式首先檢查該行中是否沒有任何位置比對 "bar"。如果 ".*bar" 在某處比對,則 \@! 會拒絕該模式。當沒有比對時,將會找到任何 "foo"。"\zs" 是為了讓比對從 "foo" 之前開始。
/\@<= \@<= 如果前一個原子在前一個比對位置之前比對,則以零寬度比對。
/zero-width 類似 Perl 中的 "(?<=pattern)",但 Vim 允許非固定寬度的模式。
比對範例
\(an\_s\+\)\@<=file 在 "an" 和空白或行尾之後的 "file" 為了提高速度,最好盡量避免使用此多重。嘗試改用 "\zs"
/\zs。為了比對與上述範例相同的內容:an\_s\+\zsfile 至少為 look-behind 設定一個限制,請參閱下方說明。
"\@<=" 和 "\@<!" 會檢查緊接在後方的內容之前是否有符合的項目。理論上,這些符合的項目可以從此位置之前的任何地方開始。但為了限制所需時間,只會搜尋後方內容符合的那一行,以及前一行(如果有的話)。這應該足以符合大多數情況,且不會太慢。
在舊的正規表達式引擎中,"\@<=" 和 "\@<!" 後面的模式部分會先檢查是否符合,因此像 "\1" 這樣的東西無法參照前面原子內的 \(\)。反過來是可以的。
不好的比對範例
\%#=1\1\@<=,\([a-z]\+\) ",abc" 在 "abc,abc" 中
然而,新的正規表達式引擎運作方式不同,最好不要依賴此行為,如果可以避免,請不要使用 \@<=。
比對範例
\([a-z]\+\)\zs,\1 ",abc" 在 "abc,abc" 中
\@123<= 類似 "\@<=",但只回溯 123 個位元組。這避免嘗試大量已知會失敗的比對,並使執行模式變得非常慢。例如,檢查 "span" 之前是否有 "<":/<\@1<=span。這只會嘗試在 "span" 前面的一個位元組比對 "<",這也是唯一可行的位置。在跨越行邊界之後,限制是相對於行尾的。因此,不計算符合行開頭的字元(這只是為了保持簡單)。數字零與沒有限制相同。
/\@<! \@<! 如果在緊接在後方的內容之前,前面的原子不符合,則以零寬度符合。因此,如果目前行或前一行中,沒有任何位置符合原子,使其結尾緊接在後方的內容之前,則符合。
/zero-width 類似 Perl 中的 "(?<!pattern)",但 Vim 允許非固定寬度的模式。與前面原子的比對會使其結尾緊接在與後方內容的比對之前,因此以 ".*" 結尾的原子會起作用。
警告:這可能會很慢(因為需要檢查許多位置是否符合)。如果可以,請使用限制,請參閱下方。
比對範例
\(foo\)\@<!bar 任何不在 "foobar" 中的 "bar" \(\/\/.*\)\@<!in 不在 "//" 後面的 "in"
\@123<! 類似 "\@<!",但只回溯 123 個位元組。這避免嘗試大量已知會失敗的比對,並使執行模式變得非常慢。
/\@> \@> 像比對整個模式一樣比對前面的原子。類似 Perl 中的 "(?>pattern)"。
比對範例
\(a*\)\@>a 無符合("a*" 會取走所有 "a",後面不可能再有另一個 "a")
這會將前面的原子視為模式本身進行比對。如果它不符合,則不會以較短的子比對或任何其他方式重試。觀察這個差異:"a*b" 和 "a*ab" 都符合 "aaab",但在第二種情況下,"a*" 只符合前兩個 "a"。 "\(a*\)\@>ab" 將不符合 "aaab",因為 "a*" 符合 "aaa"(盡可能多的 "a"),因此 "ab" 無法符合。
一般原子可以是
/^ ^ 在模式開頭或在 "\|"、"\("、"\%(" 或 "\n" 之後:符合行首;在其他位置,符合字面上的 '^'。
/zero-width比對範例
^beep( C 函數 "beep" 的開頭(可能)。
/\^ \^ 符合字面上的 '^'。可以在模式中的任何位置使用,但不能在 [] 內。
/\_^ \_^ 符合行首。
/zero-width 可以在模式中的任何位置使用,但不能在 [] 內。
比對範例
\_s*\_^foo 空白和空白行,然後是行首的 "foo"
/\$ \$ 符合字面上的 '$'。可以在模式中的任何位置使用,但不能在 [] 內。
/\_$ \_$ 符合行尾。
/zero-width 可以在模式中的任何位置使用,但不能在 [] 內。請注意,"a\_$b" 永遠不符合,因為 "b" 不能符合行尾。請改用 "a\nb"
/\n。
比對範例
foo\_$\_s* 行尾的 "foo" 以及後面的空白和空白行
/\_. \_. 符合任何單一字元或行尾。請注意:"\_.*" 符合緩衝區末尾的所有文字!
/\zs \zs 符合任何位置,但不能在 [] 內,並在那裡設定符合的開始:下一個字元是整個符合的第一个字元。
/zero-width 例如
/^\s*\zsif
符合行首的 "if",忽略空白。可以多次使用,符合分支中最後遇到的那個會被使用。例如
/\(.\{-}\zsFab\)\{3}
尋找第三次出現的 "Fab"。後面不能接著 multi。
E888
/\ze \ze 符合任何位置,但不能在 [] 內,並在那裡設定符合的結尾:前一個字元是整個符合的最後一個字元。
/zero-width 可以多次使用,符合分支中最後遇到的那個會被使用。例如:"end\ze\(if\|for\)" 符合 "endif" 和 "endfor" 中的 "end"。後面不能接著 multi。
E888
/\%$ end-of-file \%$ 符合檔案結尾。當與字串比對時,符合字串結尾。請注意,這不會尋找檔案中的最後一個 "VIM"
/VIM\_.\{-}\%$
它會尋找下一個 VIM,因為它後面的部分永遠會符合。這一個會尋找檔案中的最後一個 "VIM"
/VIM\ze\(\(VIM\)\@!\_.\)*\%$
這使用
/\@! 來確定 "VIM" 不符合第一個 "VIM" 後面的任何位置。從檔案結尾向後搜尋比較容易!
/\%V \%V 符合可視區域內部。當可視模式已經停止時,符合
gv 會重新選擇的區域。這是一個
/zero-width 比對。若要確保整個模式都在可視區域內,請將其放在模式的開頭和結尾之前,例如
/\%Vfoo.*ba\%Vr
即使只有 "foo bar" 被可視選取,這也有效。這
/\%Vfoo.*bar\%V
如果可視選取在 "r" 之後繼續,則會符合 "foo bar"。僅適用於目前的緩衝區。
/\%# cursor-position \%# 符合游標位置。僅在視窗中顯示的緩衝區中比對時有效。
警告:當在模式使用後移動游標時,結果會失效。Vim 不會自動更新比對。這對於語法高亮和
'hlsearch' 特別重要。換句話說:當游標移動時,顯示不會針對此變更更新。變更的行(整個行會更新)或使用
CTRL-L 命令(整個畫面會更新)時會進行更新。例如,要高亮顯示游標下的單字
/\k*\%#\k*
/\%'m /\%<'m /\%>'m \%'m 符合標記 m 的位置。\%<'m 符合標記 m 的位置之前。\%>'m 符合標記 m 的位置之後。例如,要高亮顯示從標記 's 到 'e 的文字
/.\%>'s.*\%<'e..
請注意,需要兩個點才能在比對中包含標記 'e。這是因為 "\%<'e" 符合 'e 標記之前的字元,而且由於它是
/zero-width 比對,因此不包含該字元。
警告:當在模式使用後移動標記時,結果會失效。Vim 不會自動更新比對。類似於移動 "\%#"
/\%# 的游標。
/\%l /\%>l /\%<l E951 E1204 \%23l 符合特定行。\%<23l 符合特定行之上(較低的行號)。\%>23l 符合特定行之下(較高的行號)。\%.l 符合游標行。\%<.l 符合游標行之上。\%>.l 符合游標行之下。這六個可用於符合緩衝區中的特定行。"23" 可以是任何行號。第一行是 1。
警告:當插入或刪除行時,Vim 不會自動更新比對。這表示語法高亮會很快變得錯誤。此外,當參考游標位置(".")且游標移動時,顯示不會針對此變更更新。使用
CTRL-L 命令時(整個畫面會更新)會進行更新。例如,要高亮顯示目前游標所在的行
:exe '/\%' .. line(".") .. 'l'
/\%c /\%>c /\%<c \%23c 符合特定欄。\%<23c 符合特定欄之前。\%>23c 符合特定欄之後。\%.c 符合游標欄。\%<.c 符合游標欄之前。\%>.c 符合游標欄之後。這六個可用於符合緩衝區或字串中的特定欄。"23" 可以是任何欄號。第一欄是 1。實際上,欄是位元組數(因此對於多位元組字元來說並不完全正確)。
警告:當插入或刪除文字時,Vim 不會自動更新比對。這表示語法高亮會很快變得錯誤。此外,當參考游標位置(".")且游標移動時,顯示不會針對此變更更新。使用
CTRL-L 命令時(整個畫面會更新)會進行更新。例如,要高亮顯示目前游標所在的欄
:exe '/\%' .. col(".") .. 'c'
當設定
'hlsearch' 並且您移動游標並進行變更時,這會清楚顯示比對是否更新。例如,要符合第 44 欄中的單一位元組
/\%>43c.\%<46c
請注意,「\%<46c」會在第 45 欄匹配,當「.」在第 44 欄匹配一個位元組時。
/\%v /\%>v /\%<v \%23v 在特定的虛擬欄位中匹配。\%<23v 在特定的虛擬欄位之前匹配。\%>23v 在特定的虛擬欄位之後匹配。\%.v 在目前的虛擬欄位匹配。\%<.v 在目前的虛擬欄位之前匹配。\%>.v 在目前的虛擬欄位之後匹配。這六個可用於在緩衝區或字串中匹配特定的虛擬欄位。當不與視窗中的緩衝區匹配時,會使用目前視窗的選項值(例如,
'tabstop')。「23」可以是任何欄位編號。第一欄是 1。請注意,某些虛擬欄位位置永遠不會匹配,因為它們位於 Tab 或其他佔用多個螢幕字元的字元的中間。
警告:當插入或刪除文字時,Vim 不會自動更新醒目標示的匹配項。這表示語法醒目標示很快就會出錯。此外,當參照游標位置(「.」)且游標移動時,不會更新此變更的顯示。當使用
CTRL-L 命令時會進行更新(會更新整個螢幕)。例如,要醒目標示虛擬欄位 72 之後的所有字元
/\%>72v.*
當設定
'hlsearch' 且您移動游標並進行變更時,這會清楚顯示匹配項是否已更新。要匹配到第 17 欄的文字
/^.*\%17v
要匹配目前虛擬欄位(游標所在位置)之後的所有字元
/\%>.v.*
第 17 欄不包含在內,因為這是一個
/零寬度 匹配。要包含該欄位,請使用
/^.*\%17v.
此命令的作用相同,但當第 17 欄中沒有字元時也會匹配
/^.*\%<18v.
請注意,如果沒有「^」來將匹配錨定在第一欄,這也會醒目標示第 17 欄
/.*\%17v
注意:上述內容也適用於多位元組字元。以下只匹配 ASCII 字元,如範圍所示。
whitespace white-space \s 空白字元:
<Space>
和
<Tab>
/\s\S 非空白字元;與 \s 相反
/\S \d 數字:[0-9]
/\d\D 非數字:[^0-9]
/\D\x 十六進位數字:[0-9A-Fa-f]
/\x \X 非十六進位數字:[^0-9A-Fa-f]
/\X \o 八進位數字:[0-7]
/\o\O 非八進位數字:[^0-7]
/\O\w 單字字元:[0-9A-Za-z_]
/\w \W 非單字字元:[^0-9A-Za-z_]
/\W \h 單字開頭字元:[A-Za-z_]
/\h \H 非單字開頭字元:[^A-Za-z_]
/\H \a 字母字元:[A-Za-z]
/\a \A 非字母字元:[^A-Za-z]
/\A \l 小寫字元:[a-z]
/\l\L 非小寫字元:[^a-z]
/\L\u 大寫字元:[A-Z]
/\u\U 非大寫字元:[^A-Z]
/\U
注意:使用原子比使用 [] 形式更快。
\e 匹配
<Esc>
/\e\t 匹配
<Tab>
/\t\r 匹配
<CR>
/\r\b 匹配
<BS>
/\b\n 匹配行尾
/\n在字串而非緩衝區文字中匹配時,會匹配文字換行字元。
\1 匹配 \( 和 \) 中第一個子運算式所匹配的相同字串。
/\1 E65 範例:「\([a-z]\).\1」匹配「ata」、「ehe」、「tot」等等。\2 類似「\1」,但使用第二個子運算式、
/\2 ...
/\3\9 類似「\1」,但使用第九個子運算式。
/\9 注意:群組的編號是根據模式中哪個「\(」先出現(由左至右),而不是根據哪個先匹配。
\%(\) 以跳脫括號括住的模式。
/\%(\) /\%( E53 與 \(\) 相同,但不將其計為子運算式。這允許使用更多群組,且速度稍微快一點。
x 單一字元,沒有特殊含義,會匹配自身
/\ /\\ \x 反斜線後接單一字元,沒有特殊含義,保留給未來擴充使用
[](使用
'nomagic':\\[])
/[] /\[] /\_[] /collection E76 \_[] 集合。這是一個以方括號括住的字元序列。它會匹配集合中的任何單一字元。
比對範例
[xyz] 任何 'x'、'y' 或 'z' [a-zA-Z]$ 行尾的任何字母字元 \c[a-z]$ 相同 [А-яЁё] 俄文字母(使用 utf-8 和 cp1251)
/[\n] 如果加上「\_」前綴,集合也會包含行尾。也可以在集合中包含「\n」來達成相同的效果。當集合以「^」開頭時,也會匹配行尾!因此,「\_[^ab]」會匹配行尾,以及除了「a」和「b」以外的任何字元。這使其與 Vi 相容:如果沒有「\_」或「\n」,集合就不會匹配行尾。
E769如果沒有 ']',Vim 不會顯示錯誤訊息,而是假設未使用任何集合。可用於搜尋 '['。但是,內部搜尋會出現 E769。請注意,在
:substitute
命令中,整個命令會變成模式。例如:「:s/[/x/」會搜尋「[/x」,並將其取代為無。它不會搜尋「[」,並將其取代為「x」!
E944 E945 如果序列以「^」開頭,則會匹配集合中「不」包含的任何單一字元:「[^xyz]」會匹配除了 'x'、'y' 和 'z' 以外的任何字元。
如果序列中的兩個字元以「-」分隔,則這是它們之間所有 ASCII 字元的完整清單的簡寫。例如,「[0-9]」會匹配任何十進位數字。如果起始字元超過結束字元,例如 [c-a],就會發生 E944。可以使用非 ASCII 字元,但在舊的 regexp 引擎中,字元值之間的差距不得超過 256。例如,在設定 re=1 後使用 [\u3000-\u4000] 進行搜尋會發出 E945 錯誤。加上 \%#=2 前綴即可修正此問題。
「函式」欄顯示所使用的程式庫函式。實作方式取決於系統。否則: (1) 對於 ASCII 使用 islower(),對於其他字元使用 Vim 內建規則。(2) 使用 Vim 內建規則 (3) 與 (1) 相同,但使用 isupper()
/[[= [==]等價類別。這表示會比對具有幾乎相同含義的字元,例如,忽略重音符號時。這僅適用於 Unicode、latin1 和 latin9。格式為:[=a=]
/[[. [..]校對元素。目前這只接受單一字元,格式為:[.a.]
/\]
若要在集合中包含字面上的 ']'、'^'、'-' 或 '\',請在其前面加上反斜線:「[xyz\]]」、「[\^xyz]」、「[xy\-z]」和「[xyz\\]]」。(注意:POSIX 不支援以這種方式使用反斜線)。對於 ']',您也可以將其設為第一個字元(在可能的 "^" 之後):「[]xyz]」或「[^]xyz]」。對於 '-',您也可以將其設為第一個或最後一個字元:「[-xyz]」、「[^-xyz]」或「[xyz-]」。對於 '\',您也可以讓它後面跟著任何不在 "^]-\bdertnoUux" 中的字元。「[\xyz]」會比對 '\'、'x'、'y' 和 'z'。最好使用 "\\",因為未來的擴充功能可能會在 '\' 之後使用其他字元。
省略尾隨的 ] 不會被視為錯誤。「[]」的作用與「[]]」相同,它會比對 ']' 字元。
當
'cpoptions' 中未包含 'l' 旗標時,會接受下列轉換: \e
<Esc>
\t
<Tab>
\r
<CR>
(不是行尾!) \b
<BS>
\n 換行符號,請參閱上方
/[\n] \d123 字元的十進制數字 \o40 字元的八進制數字,最高到 0o377 \x20 字元的十六進制數字,最高到 0xff \u20AC 多位元組字元的十六進制數字,最高到 0xffff \U1234 多位元組字元的十六進制數字,最高到 0xffffffff
注意:上面提到的其他反斜線代碼在 [] 內無效!
使用集合進行比對可能會很慢,因為必須將文字中的每個字元與集合中的每個字元進行比較。盡可能使用上面的其他原子。範例:"\d" 比 "[0-9]" 快得多,並且比對相同的字元。不過,新的
NFA regexp 引擎比舊的引擎更能處理這個問題。
/\%[] E69 E70 E369 \%[] 一個選擇性比對原子的序列。這永遠會比對成功。它會比對它所包含的原子列表中盡可能多的項目。因此它會在第一個不比對的原子處停止。例如
/r\%[ead]
會比對 "r"、"re"、"rea" 或 "read"。使用比對到的最長字串。若要比對 Ex 命令 "function",其中 "fu" 是必要的,而 "nction" 是選擇性的,這會起作用
/\<fu\%[nction]\>
使用字尾原子 "\>" 來避免比對 "full" 中的 "fu"。當原子不是一般字元時,會變得更複雜。您不常需要使用它,但是有可能。範例
/\<r\%[[eo]ad]\>
會比對單字 "r"、"re"、"ro"、"rea"、"roa"、"read" 和 "road"。[] 內部不能有 \(、\%( 或 \z( 項目,且 \%[] 不會巢狀化。若要包含 "[",請使用 "[[]",若要包含 "]",請使用 "[]]",例如
/index\%[[[]0[]]]
會比對 "index"、"index["、"index[0" 和 "index[0]"。
\%d123 比對以十進制數字指定的字元。後面必須跟著非數字。 \%o40 比對以八進制數字指定的字元,最高到 0o377。小於 0o40 的數字後面必須跟著非八進制數字或非數字。 \%x2a 比對以最多兩個十六進制字元指定的字元。 \%u20AC 比對以最多四個十六進制字元指定的字元。 \%U1234abcd 比對以最多八個十六進制字元指定的字元,最高到 0x7fffffff
範例
foo 關閉 - foo foo 開啟 - foo Foo FOO Foo 開啟 關閉 foo Foo FOO Foo 開啟 開啟 Foo \cfoo - - foo Foo FOO foo\C - - foo
技術細節:
NL-used-for-Nul
檔案中的
<Nul>
字元會以記憶體中的
<NL>
形式儲存。在顯示中,它們會顯示為 "^@"。此轉換會在讀取和寫入檔案時完成。若要使用搜尋模式比對
<Nul>
,您可以直接輸入
CTRL-@
或 "CTRL-V 000"。這可能正是您所期望的。在內部,該字元會以搜尋模式中的
<NL>
取代。不尋常的是,輸入
CTRL-V
CTRL-J
也會插入
<NL>
,因此也會搜尋檔案中的
<Nul>
。
使用運算式求值時,模式中的 <NL>
字元會比對字串中的 <NL>
。「\n」(反斜線 n) 無法在這裡比對 <NL>
,它僅能比對緩衝區中的文字。
/\Z 當 "\Z" 出現在模式中的任何位置時,會忽略所有組成字元。因此,只需要比對基本字元,組成字元可能會不同,而且組成字元的數量可能會有所不同。例外情況:如果模式以一個或多個組成字元開始,則必須比對它們。
/\%C使用 "\%C" 來略過任何組成字元。例如,模式 "a" 無法在 "càt" 中比對 (其中的 a 具有組成字元 0x0300),但 "a\%C" 可以。請注意,這不會比對 "cát" (其中的 á 是字元 0xe1,它沒有組成字元)。它會比對 "cat" (其中的 a 只是一個 a)。
當組成字元出現在模式的開頭或在不包含組成字元的項目之後時,會在包含此組成字元的任何字元找到比對。
當使用點和組成字元時,其作用與組成字元本身相同,只不過它不重要這個字元之前是什麼。
組成字元的順序並不重要。此外,文字可能比模式具有更多組成字元,它仍然會比對成功。但是模式中的所有組成字元都必須在文字中找到。
假設 B 是一個基本字元,而 x 和 y 是組成字元
模式 文字 比對結果
Bxy Bxy 是 (完美比對) Bxy Byx 是 (忽略順序) Bxy By 否 (缺少 x) Bxy Bx 否 (缺少 y) Bx Bx 是 (完美比對) Bx By 否 (缺少 x) Bx Bxy 是 (忽略額外 y) Bx Byx 是 (忽略額外 y)
Vim 的正規表示式在您能做的事情方面,與 Perl 的正規表示式最相似。它們之間的差異主要只是符號;以下是它們差異的摘要
Vim 語法中的功能 Perl 語法中的功能
強制區分大小寫 \c (?i) 強制區分大小寫 \C (?-i) 無反向參照的分組 \%(atom\) (?:atom) 保守量詞 \{-n,m}
*?,
+?, ??, {}? 零寬度匹配原子\@= (?=atom) 零寬度不匹配原子\@! (?!atom) 零寬度前向匹配原子\@<= (?<=atom) 零寬度前向不匹配原子\@<! (?<!atom) 不重試的匹配原子\@> (?>atom)
Vim 和 Perl 處理字串中的換行字元的方式略有不同
在 Perl 中,^ 和 $ 預設只會比對文字的最開頭和結尾,但您可以設定 'm' 旗標,使其也能比對嵌入的換行符號。您也可以設定 's' 旗標,使 . 也會比對換行符號。(順帶一提,這兩個旗標都可以在模式中使用與上述 i 旗標相同的語法來變更。)
另一方面,Vim 的 ^ 和 $ 總是比對嵌入的換行符號,並且您會得到兩個獨立的原子 \%^ 和 \%$,它們分別只比對文字的最開頭和結尾。Vim 透過提供 \_ "修飾符" 來解決第二個問題:將它放在 . 或字元類別前面,它們也會比對換行符號。
最後,這些結構是 Perl 獨有的
在 regex 中執行任意程式碼:(?{perl code})
條件表達式:(?(condition)true-expr|false-expr)
...而這些是 Vim 獨有的
變更模式的 magic 程度:\v \V \m \M (對於避免反斜線過多非常有用)
選擇性匹配原子的序列:\%[atoms]
\& (它之於 \| 就如同 "and" 之於 "or";它強制多個分支在同一個位置匹配)
依數字比對行/欄:\%5l \%5c \%5v
設定匹配的開始和結束:\zs \ze
語法 vs 比對 請注意,比對醒目標示機制獨立於
語法醒目標示,後者(通常)是緩衝區本地的醒目標示,而比對是視窗本地的,兩種方法可以自由混合使用。比對醒目標示函式在應用時間和方式上提供更多的彈性,但通常僅用於臨時醒目標示,而沒有嚴格的規則。兩種方法都可用於隱藏文字。
:mat :match :mat[ch]
{group}
/{pattern}/ 定義一個要在目前視窗中醒目標示的模式。它將以
{group}
醒目標示。範例
:highlight MyGroup ctermbg=green guibg=green
:match MyGroup /TODO/
可以使用任何字元來標記 {pattern}
的開始和結束,而不是 //。請注意不要使用特殊字元,例如 '"' 和 '|'。
{group}
必須在執行此命令時存在。
請注意,使用
'hlsearch' 醒目標示上次使用的搜尋模式會在所有視窗中使用,而使用 ":match" 定義的模式僅存在於目前視窗中。當切換到另一個緩衝區時,它會被保留。
當比對行尾,且 Vim 只重繪部分顯示時,您可能會得到非預期的結果。這是因為 Vim 會在開始重繪的行中尋找比對。
另一個範例,它會醒目標示虛擬欄 72 及之後的所有字元
:highlight rightMargin term=bold ctermfg=blue guifg=blue
:match rightMargin /.\%>72v/
醒目標示虛擬欄 7 中的所有字元
:highlight col8 ctermbg=grey guibg=grey
:match col8 /\%<8v.\%>7v/
請注意使用兩個項目來比對佔用一個以上虛擬欄的字元,例如 TAB。
:mat[ch] :mat[ch] none 清除先前定義的比對模式。
:2mat[ch]
{group}
/{pattern}/
:2match:2mat[ch] :2mat[ch] none :3mat[ch]
{group}
/{pattern}/
:3match:3mat[ch] :3mat[ch] none 和上面的
:match 一樣,但設定不同的比對。因此,可以同時啟用三個比對。如果多個比對位於相同的位置,則數字最小的比對具有優先順序。它使用比對 ID 3。":3match" 命令由(較舊的 Vim)
matchparen 外掛程式使用。建議您使用 ":match" 進行手動比對,並使用 ":2match" 進行其他外掛程式,或者最好使用更靈活的
matchadd()(以及類似的)函式。
模糊比對是指使用不完全的搜尋字串來比對字串。如果搜尋字串中的所有字元都以相同的順序出現在字串中的任何位置,則模糊比對將會比對該字串。會忽略大小寫。在比對的字串中,搜尋字串中兩個連續字元之間可能會出現其他字元。如果搜尋字串有多個單字,則每個單字會個別比對。因此,搜尋字串中的單字可以以任何順序出現在字串中。
模糊比對會根據以下準則為每個比對的字串指派分數
連續匹配的字元數。
兩個連續匹配字元之間的字元數(距離)。
在單字開頭的比對
在駝峰式大小寫字元 (例如 CamelCase 中的 Case) 的比對
在路徑分隔符或連字號之後的比對。
字串中未比對的字元數。首先傳回分數最高的比對字串。
例如,當您使用模糊比對搜尋 "get pat" 字串時,它會比對 "GetPattern"、"PatternGet"、"getPattern"、"patGetter"、"getSomePattern"、"MatchpatternGet" 等字串。
:vimgrep
的 "f" 旗標會啟用模糊比對。