基本正则表达式

Vim 是个文本编辑器,这就意味着你大部分的Vimscript代码都应该专注于处理文本。 Vim 支持强大的正则表达式,但依旧有些诡异的地方。

在缓冲中键入以下文本:

max = 10

print "Starting"

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

print "Done"

我们就用这段文本来验证 Vimscript 支持的正则表达式。 这刚好是一段Python代码,但是如果你不了解Python也不用担心。这只是个例子。

我假设你知道基本的正则表达式。如果不知道,那应该停止阅读本书,并且阅读Zed Shaw写的 Learn Regex the Hard Way。等完成了之后再回来。

高亮显示

在开始之前,我们需要开启搜索高亮,这样就能看到我们正在做什么。运行以下命令:

:set hlsearch incsearch

hlsearch 告诉 Vim 在执行一次搜索时,高亮显示文件中所有的匹配,而 incsearch 告诉 Vim` 在仍然输入搜索模式时,就高亮显示下个匹配。

搜索

把光标放到文件的顶部,运行以下命令:

/print

随着你键入每一个字母,Vim 都会在第一行中高亮显示它们。 当你按下回车来执行搜索时,所有print 实例会高亮显示,并且光标会移动到下一个匹配。

现在试试运行以下命令:

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

这会移动到文件顶部,搜索 print,并移动到第一个匹配。 这是用:execute "normal! .."来实现的,我们在上一章节刚讲过的。

要到达文件中第二个匹配的话,你只要在字符串末尾处添加更多命令。运行命令:

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

Vim 会把光标移到缓冲中的第二个 print 处(并且所有的匹配都会高亮显示)。

让我们试试反向搜搜。运行命令:

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

这次,我们使用 G 移动到文件底部,然后用 ? 来反向搜索,而不是正向。

所有的这些搜索命令应该很熟悉了——我们重点讲过它们,让你习惯于 :execute "normal! ...", 因为你知道的任何 Vim 中的操作都可以通过这个在 Vimscript 代码中实现。

magic 模式

/? 命令实际上接受正则表达式,不仅仅是字面字符。运行以下命令:

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

Vim 会抱怨找不到这个!我们已经告诉了你 Vim 支持正则表达式搜索,那么发生了什么? 试试以下命令:

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

这次正如我们所期望的, Vim 一开始就高亮显示“for”循环。 在继续之前,先花上一分钟,试着想想到底修改了什么。 记住,execute 仅仅接收一个字符串作为参数。

答案有两个原因,使得我们必须像那样写这命令:

通过直接在 Vim 中运行搜索可以让你更容易理解。键入以下命令,并按下返回:

/print .\+

现在,你能看到 \+ 正常运作。而双反斜杠被使用只是因为我们要把正则模式作为一个字符串传给 execute

字面字符串

正如我们在字符串章节提到的,Vim 允许你使用单引号来定义一个“字面字符串”,并作为字符串被直接传递。 例如,字符串 'a\nb' 就是四个字符。

我们可以使用字面字符串来避免键入那些双反斜杠吗? 在我们继续之前,考虑一两分钟,因为答案可能比你想象的要复杂一些。

试试运行一下命令(注意是单引号和单反斜杠):

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

Vim 移动到文件顶部,但是没有移动到第一个匹配。这是你所期望的吗?

这命令没有正常工作,因为我们需要正则模式中的 \<cr> 被转义为一个实际的回车键字符, 并让搜索命令真正的运行。因为现在是一个字面字符串,这就相当于在 Vim 中键入 /for .\+ in .\+:\<cr>,而这明显不是我们想要的。

尽管如此,还是有办法的!记住,Vim 允许你连接字符串,所以对于比较长的命令, 我们可以把字符串分割为更容易理解的语块。运行以下命令:

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

这命令连接了三个更短的字符串,然后传给给 execute, 并且让我们可以用字面字符串表示正则表达式,而用普通字符串表示其他的。

very magic 模式

你也许想知道 Vimscript 的四种不同的解析正则表达式的模式,以及和类似Python、 Perl或者Ruby这些语言有何不同。如果你真想知道,可以阅读它们的文档,但是如果还想保持理智, 最简单的解决办法就是接着往下看。

运行以下命令:

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

我们已经再次把正则模式从命令中分割出来了,并作为单独的字面字符串,这次我们从 \v开始。 这告诉 Vim 使用“very magic"模式,这和你以前在其他编程语言中使用的几乎一样。

如果简便地在所有表达式之前加上 \v,你就完全不用顾忌 Vimscript 的其他三种疯狂的模式了。

练习

仔细阅读 :help magic

阅读 :help pattern-overview,看看 Vim 正则支持些什么。到character classes就停止吧。

阅读 :help :match。试试手动运行几次 :match Error \/v.../ 命令。

编辑 ~/.vimrc 文件,添加一个映射,使其用 match 来高亮显示行尾空白来表示错误。 <leader>w可能是个不错的选择。

添加另一个映射,使其能清除匹配(可以选用 <leader>W)。

添加一个普通模式映射,使其能为搜索自动添加 \v。如果卡壳了,只要记住 Vim 的映射是非常简单的,你仅仅需要告诉它在用了映射的键后,实际要按下哪些键就行了。

~/.vimrc 文件中添加 hlsearchincsearch 选项,按照你喜欢的去设置就行。

阅读 :help nohlsearch。注意这是一个命令,而不是 hlsearch 设置的“关闭模式”!

~/.vimrc 文件中添加一个映射,使其“取消最近一次搜索的高亮显示”。

原文地址:http://learnvimscriptthehardway.stevelosh.com/chapters/31.html