USR_27

*usr_27.txt*	For Vim version 7.1.	最近更新:2005年3月

		     VIM 用户手册 - Bram Moolenaar 著
		  译者: Chimin Yen http://vimcdoc.sf.net

			     查找命令及模式


在第三章里,我们曾经提到过几个简单的查找模式 |03.9|。Vim 能够胜任复杂得多的查
找。本章将解释那些最常用到的模式。详细的说明可以查阅: |pattern|

|27.1|	忽略大小写
|27.2|	在文件尾折返
|27.3|	偏移
|27.4|	匹配重复性模式
|27.5|	多择一
|27.6|	字符范围
|27.7|	字符类
|27.8|	匹配换行符
|27.9|	举例

       下一章: |usr_28.txt|  折叠
       前一章: |usr_26.txt|  重复
         目录: |usr_toc.txt|


*27.1*	忽略大小写

默认情况下,Vim 的查找是大小写敏感的。因此,"include","INCLUDE",和 "Include"
为三个各不相同的词,而一次查找将仅仅匹配其中的一个。
   现在设定 'ignorecase' 选项:

	:set ignorecase

再查找 "include",现在它将匹配 "Include","INCLUDE" 和 "InClUDe"。(设定
'hlsearch' 选项可以快速查看哪儿有模式的匹配。)
   你可以这样撤销这个选项:

	:set noignorecase

让我们保留这个设定,并查找 "INCLUDE"。它匹配的文本就跟查找 "include" 时一模一
样。现在我们设定 'smartcase' 选项:

	:set ignorecase smartcase

如果你采用的模式里至少有一个大写字母,查找就成了大小写敏感的。可以这样理解,你
不必键入大写字母,也能查找到含有大写字母的词,所以,你若键入大写字母,必然是因
为你要大小写敏感的匹配。聪明!
    设定了这两个选项,你会找到以下匹配:

	模式			匹配	
	word			word、Word、WORD、WoRd 等。
	Word			Word
	WORD			WORD
	WoRd			WoRd


单 个 模 式 里 的 大 小 写

如果你仅想忽略一个特定的模式里的大小写,那么,在模式前添加 "\c" 字符串就行了。
添加 "\C" 将使该模式的匹配大小写敏感。这排除了 'ignorecase' 和 'smartcase' 选
项的影响,当 "\c" 或 "\C" 起作用时,它们设成什么值无关紧要。

	模式			匹配	
	\Cword			word
	\CWord			Word
	\cword			word,Word,WORD,WoRd,等。
	\cWord			word,Word,WORD,WoRd,等。

采用 "\c" 和 "\C" 的好处在于它粘附在所用的模式上。因此,重复查找历史记录里的某
个模式会产生同样的结果。'ignorecase' 或 'smartcase' 是否更改不影响结果。

	备注:
	在查找模式中使用以 "\" 开头的项,其效果取决于 'magic' 选项。在本章中,
	我们将假定 'magic' 为真。这也是标准和建议的设定。如果你把它改了,那
	么,许多查找模式就会突然变得无效了。

	备注:
	如果你查了好久,超过了你预计的时间,你可以中断查找,在 Unix 上用
	CTRL-C,而在 MS-DOS 和微软视窗上则用 CTRL-Break

*27.2*	在文件尾折返

在默认情况下,正向查找从当前光标位置开始,查找特定的字符串。然后它就遇到了文件
尾。如果那个时候还没找到那个字符串,它就从头来过,从文件开头一直查到光标处。
   记住,当你不断以 "n" 命令查找下一个匹配时,你最终回到第一个匹配。如果你不
注意,你将永远找下去!为了提醒你,Vim 显示如下信息:

	search hit BOTTOM,continuing at TOP 

如果你使用 "?" 命令按相反方向查找,你得到的信息是这样的:

	search hit TOP,continuing at BOTTOM 

可是,你还是不知道你何时回到了第一个匹配。一种办法是设定 'ruler' 选项:

	:set ruler

Vim 将把光标位置显示在窗口的右下角 (如果使用了状态条的话,会显示在哪里)。看起
来像这样:

	101,29       84% 

第一个数字是光标所在的行号。在你开始查找的时候记住行号,那样你就能检查是否越过
了该位置。


无 折 返 查 找

要取消查找折返功能,请用以下命令:

	:set nowrapscan

现在当查找遇到文件末尾,一个出错信息就会显示出来:

	E385: search hit BOTTOM without match for: forever 

这样,你只要用 "gg" 命令回到文件开头,并一直查到你看到以上信息,你就能找到所有
的匹配。
   如果你用 "?" 从相反方向查找,你将得到:

	E384: search hit TOP without match for: forever 


*27.3*	偏移

在默认情况下,查找命令让光标停留在匹配的模式的开始。你可以指定一个偏移,告诉
Vim 将光标停留在别的位置上。在正向查找命令 "/" 中指定偏移,就是在模式后面附加
一个斜线符 (/) 以及偏移值:

	/默认/2

这个命令查找模式 "默认"。找到后使光标越过匹配的模式而前移两行,并停留在该行的
行首。把这个命令用于以上段落中,Vim 在第一行找到词 "默认"。接着光标再往下移两
行,落在 "一个" 的 "一" 上。

如果该偏移为一简单数字,那么光标就会被放置在距离匹配那么多行的那一行的行首。该
偏移值可为正数或负数。如果它是正数,光标会向前移该数表示的行;若为负数,则往回
退该数表示的行。


字 符 偏 移

偏移符 "e" 表示一个偏移从匹配末尾算起。它把光标移到匹配的最后一个字符上。命
令:

	/const/e

把光标放到单词 "const" 的 "t" 上。
   加一个数字,光标就从该位置再前移该数字指定的那么多个字符。下面这个命令会将
光标移到匹配后面第一个字符:

	/const/e+1

一个正数使光标右移,负数使其左移。例如:

	/const/e-1

会把光标移到单词 "const" 的 "s" 字符上。

如果偏移以 "b" 开头,那么光标就移到匹配模式的首位。因为不用 "b" 光标也一样会被
移到首位,所以单独使用时没什么意义。在将它与一个加上或减去的数字合起来时,就很
有用了。光标就会前移或后移那么多个字符。例如:

	/const/b+2

会把光标移到匹配的首位,再往右移两个字符。因而落在字符 "n" 上。


重 复

当你重复前一次使用过的查找模式,只是偏移不同时,你可以把模式省略了:

	/that
	//e

等于:

	/that/e

再以同样的偏移重复查找:

	/

命令 "n" 具有同样的作用。要取消一个以前用过的偏移可以用:

	//


反 向 查 找

命令 "?" 以相同的方式使用偏移,但你必须以 "?" 来分隔模式和偏移,而非 "/":

	?const?e-2

偏移符 "b" 和 "e" 的用途是一样的。它们并不因为使用了 "?" 而改变方向。


起 始 位 置

查找时,通常从光标位置开始。当你规定的是一个行偏移,这可能造成麻烦。例如:

	/const/-2

这个命令找到下一个单词 "const",然后上移两行。如果你用命令 "n" 再找,Vim 就从
当前位置开始,找到同一个 "const" 匹配。然后再一次在偏移的作用下,回到开始的地
方。你给套住了!
   还有比这更糟糕的: 假定下一行另有一个 "const" 匹配。那么,重复正向查找就会找
到这个匹配,并上移两行。这样你实际上把光标往回移了!

当你规定的是一个字符偏移,Vim 将为其作调整。因此,查找会向前或向后跳过几个字符
再开始,以便同一个匹配不至于再出现。


*27.4*	匹配重复性模式

星号项 "*" 规定在它前面的项可以重复任意次。因此:

	/a*

匹配 "a","aa","aaa",等等。但也匹配 "" (空字串),因为零次也包含在内。
   星号 "*" 仅仅应用于那个紧邻在它前面的项。因此 "ab*" 匹配 "a"、"ab"、"abb"、
"abbb" 等等。如要多次重复整个字符串,那么该字符串必须被组成一个项。组成一项的
方法就是在它前面加 "\(",后面加 "\)"。因此这个命令:

	/\(ab\)*

匹配: "ab","abab","ababab",等等。而且也匹配 ""。

要避免匹配空字串,使用 "\+"。这表示前面一项可以被匹配一次或多次。

	/ab\+

匹配 "ab"、"abb"、"abbb" 等等。它不匹配后面没有跟随 "b" 的 "a"。

要匹配一个可选项,用 "\="。 例如:

	/folders\=

匹配 "folder" 和 "folders"。


指 定 重 复 次 数

要匹配某一项的特定次数重复,使用 "\{n,m}" 这样的形式。其中 "n" 和 "m" 都是数
字。在它前面的那个项将被重复 "n" 到 "m" 次 (|inclusive| 包含 "n" 和 "m")。例
如 :


	/ab\{3,5}

匹配 "abbb"、"abbbb" 以及 "abbbbb"。
  当 "n" 省略时,被默认为零。当 "m" 省略时,被默认为无限大。当 ",m" 省略时,就
表示重复正好 "n" 次。例如:

	模式		匹配次数 
	\{,4}		0,1,2,3 或 4
	\{3,}		3,4,5 等等
	\{0,1}		0 或 1,同 \=
	\{0,}		0 或更多,同 *
	\{1,}		1 或更多,同 \+
	\{3}		3


匹配尽可能少的字符

迄今为止,我们所讨论过的都试图匹配尽可能多的字符。若要匹配尽可能少的字符,请用
"\{-n,m}"。它的用法跟 "\{n,m}" 一样,唯一的区别在于,它采用尽可能少的字符。
   例如,以下命令:

	/ab\{-1,3}

将匹配 "abbb" 中的 "ab"。实际上,因为没理由匹配更多,所以它永远不会匹配超过一
个 b。它需要其它的来强制它超过其下限规定次数,而匹配更多的重复。
   这些同样的规则也适用于省略 "n" 和 "m" 的情形。甚至可以把两个都省略,只剩
"\{-}"。这个项匹配其前项的重复,重复次数尽可能少,可以等于或大于零。这个项如单
独使用,则总是匹配前项的零次重复。当它跟与其它的模式合起来时,用处就大了。例
如:

	/a.\{-}b

这个命令匹配 "axbxb" 中的 "axb"。如果采用了下面这个模式:

	/a.*b

由于 ".*" 匹配尽可能多的字符,整个 "axbxb" 都会被匹配。


*27.5*	多择一

在一个查找模式中,"或" 运算符是 "\|"。例如:

	/foo\|bar

这个命令匹配了 "foo" 或 "bar"。更多的抉择可以连在后面:

	/one\|two\|three

匹配 "one"、"two" 或 "three"。
   如要匹配其多次重复,那么整个抉择结构须置于 "\(" 和 "\)" 之间:

	/\(foo\|bar\)\+

这个命令匹配 "foo"、"foobar"、"foofoo"、"barfoobar" 等等。
   再举个例子:

	/end\(if\|while\|for\)

这个命令匹配 "endif"、"endwhile" 和 "endfor"。

一个与此相关的项是 "\&"。它要求两个抉择都与同一位置的文本相符。而最终匹配的则
是最后面的那个抉择。例如:

	/forever\&...

这个命令匹配 "forever" 中的 "for" (译者: 因为第二抉择要求三个字符)。它将不匹
配,比如说 "fortuin" (译者: 不符合第一抉择)。


*27.6*	字符范围

你可以用 "/a\|b\|c" 来匹配 "a","b" 或 "c"。当你需要匹配自 "a" 至 "z" 所有的字
母时,以这样的方式表达就嫌长了。这里有个比较简短的表达方式:

	/[a-z]

方括号结构 [] 匹配单个字符。你在括号内指定哪些字符可以匹配。你可以把一系列字符
包含在内,像这样:

	/[0123456789abcdef]

这个命令将匹配其中的任何一个字符。你可以为一系列连续字符规定一个字符范围。
"0-3" 表示 "0123"。"w-z" 表示 "wxyz"。因此,上面那个命令可以缩短为:

	/[0-9a-f]

若要匹配字符 "-" 本身,就得把它放在字符范围的第一或最后的位置上。Vim 会识别下
面这些特殊字符,以便在 [] 字符范围里较为方便地使用它们 (它们实际上可被用于任何
查找模式的任何地方):

	\e	<Esc>
	\t	<Tab>
	\r	<CR>
	\b	<BS>

还有若干特殊场合用得上 [] 字符范围,参阅 |/[]| 以了解全部用法。


范 围 求 反

为了避免匹配到一个特定的字符,在字符范围首位使用 "^"。这样方括号项 [] 就会匹配
任何括号内不包括的字符。例如:

	/"[^"]*"

	 "	  双引号
	  [^"]	  双引号以外的任何字符
	      *	  尽可能多个
	       "  又一个双引号

这个命令匹配 "foo" 和 "3!x",包含双引号在内。


预 定 义 范 围

有些字符范围使用得很频繁。Vim 为这些字符范围提供了一些快捷方式。例如:

	/\a

这个命令找寻字母字符。这相当于使用 "/[a-zA-Z]"。下面还有几个这样的字符范围:

	项	匹配			相当于 
	\d	数位			[0-9]
	\D	非数位			[^0-9]
	\x	十六进制数位		[0-9a-fA-F]
	\X	非十六进制数位		[^0-9a-fA-F]
	\s	空白字符		[ 	]     (<Tab><Space>)
	\S	非空白字符		[^ 	]     (非 <Tab><Space>)
	\l	小写字母		[a-z]
	\L	非小写字母		[^a-z]
	\u	大写字母		[A-Z]
	\U	非大写字母		[^A-Z]

	备注:
	使用这些预定义的字符范围要比使用它们所表示的那个字符范围快很多。
	这些项不能用于 [] 方括号内。因此 "[\d\l]" 不能用来匹配一个数字或一个小
	写字母。请换用 "\(\d\|\l\)"。

|/\s| 包括一个这类范围的完整的列表。


*27.7*	字符类

一个特定的字符范围匹配一组固定的字符。一个字符类与字符范围相似,不过有个本质的
区别: 一个字符类代表的那组字符可以重新定义而无须改动查找模式。
   例如,查找这个模式:

	/\f\+

其中 "\f" 项表示文件名字符。因而这个命令匹配一个由可用作文件名的字符字符组成的
序列。
   哪些字符可以用来组成文件名取决于你所使用的系统。在微软视窗上,反斜杠可以,
而在 Unix 上却不行。文件名字符由 'isfname' 选项来规定。在 Unix 上,该选项的默
认值为:

	:set isfname
	isfname=@,48-57,/,.,-,_,+,,,#,$,%,~,=

在其它系统上,其默认值各不相同。因此你可以用 "\f" 组成一个查找模式,以匹配一个
文件名。该查找模式将自动调整以适应你所使用的系统。

	备注:
	实际上,Unix 允许在文件名里使用几乎所有的字符,包括空格字符。把这些字
	符包括在 'isfname' 里,在理论上是没错的。但那样就无法在文本中发现一个
	文件名在哪儿结束。因此选项 'isfname' 的默认值是个折衷方案。

字符类有如下这些:

	项	匹配				选项 
	\i	标识符字符			'isident'
	\I	类似于 \i,但不包括数字字符
	\k	关键词字符			'iskeyword'
	\K	类似于 \k,但不包括数字字符
	\p	可显示字符			'isprint'
	\P	类似于 \p,但不包括数字字符
	\f	文件名字符			'isfname'
	\F	类似于 \f,但不包括数字字符


*27.8*	匹配换行符

Vim 能找寻含有换行符的模式。你需要指定换行符在哪儿出现,因为迄今为止所有我们
曾经提到过的项,都不匹配换行符。
   用 "\n" 项可以在一个特定的位置查验一个换行符:

	/the\nword

这个命令将在一行以 "the" 结尾,而下一行以 "word" 开头的地方找到匹配。如果还要
匹配 "the word",那么你需要匹配一个空格或一个换行符。这可以用 "\_s" 表示:

	/the\_sword

若要允许任意数量的空格:

	/the\_s\+word

这个命令也匹配 "the  " 在行尾,及 "   word" 在下一行行首的情形。

"\s" 匹配空格字符,"\_s" 匹配空格字符或一个换行符。同理,"\a" 匹配一个字母字
符,而 "\_a" 匹配一个字母字符或一个换行符。其它字符类和字符范围都可以通过插入
一个 "_" 来更改其范围。

很多别的项也可以在前面加 "\_" 以匹配一个换行符。例如: "\_." 匹配任意字符或一个
换行符。

	备注:
	"\_.*" 匹配任何字符,直至文件结束。要小心,它会使查找命令执行得非常缓
	慢。

另一个例子是 "\_[]",一个包含了换行符的字符范围:

	/"\_[^"]*"

这个命令找寻位于一对双引号之间,可能分隔成数行的文本。


*27.9*	举例

这儿有几个查找模式,你也许会觉得有用。本节向你演示如何综合使用前面提及的那些
用法。


寻 找 一 个 加 州 驾 驶 牌 照

有一个驾驶牌照号码为 "1MGU103"。它有一个数字,三个大写字母,然后三位数字。直接
把这个号码放入查找模式:

	/\d\u\u\u\d\d\d

另一种方法是用一个计数器来指定其中有三个数字和三个字母:

	/\d\u\{3}\d\{3}

换用 [] 字符范围方法:

	/[0-9][A-Z]\{3}[0-9]\{3}

这些方法之中你应该使用哪一种?挑那种你记得住的。你记得住的简单方法要比你记不住
的华丽方法快得多。如果你能把它们都记住,那么避免使用最后那种,因为它要打的字
多,而且执行起来慢。


寻 找 一 个 标 识 符

在 C 程序里 (以及其它很多计算机程序) 一个标识符以字母开头,其余部分由字母和数
字组成。下划线字符也可以。这样一个标识符可以用下面的命令找到:

	/\<\h\w*\>

"\<" 和 "\>" 用来寻找那些完整的词。"\h" 表示 "[A-Za-z_]",而 "\w" 则表示
"[0-9A-Za-z_]"。

	备注:
	"\<" 和 "\>" 取决于 'iskeyword' 选项。如果这个选项包括 "-" 的话,那么
	 "ident-" 就不匹配了。在这种情况下,请用:

		/\w\@<!\h\w*\w\@!

	这个命令查验是否 "\w" 不匹配标识符之前或之后的字符。
	参见 |/\@<!| 和 |/\@!|。


下一章: |usr_28.txt|  折叠

版权: 参见 |manual-copyright|  vim:tw=78:ts=8:ft=help:norl:

Generated by vim2html on 2008年 03月 27日 星期四 17:04:45 CST