毋庸多言,在vim中正则表达式得到了十分广泛的应用。 最常用的 / 和 :s 命令中,正则表达式都是不可或缺的。 下面对vim中的正则表达式的一些难点进行说明。
关于magic
vim中有个magic的设定。设定方法为:
:set magic " 设置magic :set nomagic " 取消magic :h magic " 查看帮助
vim毕竟是个编辑器,正则表达式中包含的大量元字符如果原封不动地引用(像perl那样), 势必会给不懂正则表达式的人造成麻烦,比如 /foo(1) 命令, 大多数人都用它来查找foo(1)这个字符串, 但如果按照正则表达式来解释,被查找的对象就成了 foo1 了。
于是,vim就规定,正则表达式的元字符必须用反斜杠进行转义才行, 如上面的例子,如果确实要用正则表达式,就应当写成 /foo\(1\) 。 但是,像 . * 这种极其常用的元字符,都加上反斜杠就太麻烦了。 而且,众口难调,有些人喜欢用正则表达式,有些人不喜欢用……
为了解决这个问题,vim设置了 magic 这个东西。简单地说, magic就是设置哪些元字符要加反斜杠哪些不用加的。 简单来说:
- magic(\m):除了 $ . * ^ 之外其他元字符都要加反斜杠。
- nomagic(\M):除了 $ ^ 之外其他元字符都要加反斜杠。
这个设置也可以在正则表达式中通过 \m \M 开关临时切换。 \m 后面的正则表达式会按照 magic 处理,\M 后面的正则表达式按照 nomagic 处理, 而忽略实际的magic设置。
例如:
/\m.* # 查找任意字符串 /\M.* # 查找字符串 .* (点号后面跟个星号)
另外还有更强大的 \v 和 \V。
- \v(即 very magic 之意):任何元字符都不用加反斜杠
- \V(即 very nomagic 之意):任何元字符都必须加反斜杠
例如:
/\v(a.c){3}$ # 查找行尾的abcaccadc
/\m(a.c){3}$ # 查找行尾的(abc){3}
/\M(a.c){3}$ # 查找行尾的(a.c){3}
/\V(a.c){3}$ # 查找任意位置的(a.c){3}$
默认设置是 magic,vim也推荐大家都使用magic的设置,在有特殊需要时,直接通过 \v\m\M\V 即可。
本文下面使用的元字符都是 magic 模式下的。
量词
vim的量词与perl相比一点也不逊色。
| vim | Perl | 意义 |
| * | * | 0个或多个(匹配优先) |
| \+ | + | 1个或多个(匹配优先) |
| \? 或 \= | ? | 0个或1个(匹配优先),\?不能在 ? 命令(逆向查找)中使用 |
| \{n,m} | {n,m} | n个到m个(匹配优先) |
| \{n,} | {n,} | 最少n个(匹配优先) |
| \{,m} | {,m} | 最多m个(匹配优先) |
| \{n} | {n} | 恰好n个 |
| \{-n,m} | {n,m}? | n个到m个(忽略优先) |
| \{-} | *? | 0个或多个(忽略优先) |
| \{-1,} | +? | 1个或多个(忽略优先) |
| \{-,1} | ?? | 0个或1个(忽略优先) |
从上表中可见,vim的忽略优先量词不像perl的 *? +? ?? 那样,而是统一使用 \{- 实现的。 这大概跟忽略优先量词不常用有关吧。
环视和固化分组
vim居然还支持环视和固化分组的功能,强大,赞一个
关于环视的解释请参考Yurii的《精通正则表达式》一书吧。
| vim | Perl | 意义 |
| \@= | (?= | 顺序环视 |
| \@! | (?! | 顺序否定环视 |
| \@<= | (?<= | 逆序环视 |
| \@<! | (?<! | 逆序否定环视 |
| \@> | (?> | 固化分组 |
| \%(atom\) | (?: | 非捕获型括号 |
和perl稍有不同的是,vim中的环视和固化分组的模式的位置与perl不同。 例如,查找紧跟在 foo 之后的 bar,perl将模式写在环视的括号内, 而vim将模式写在环视的元字符之前。
# Perl的写法 /(?<=foo)bar/ # vim的写法 /\(foo\)\@<=bar
参考
vim的帮助文件非常有用,关于正则表达式可以参考以下的内容。
:h pattern :h magic :h perl-patterns
很短很好用,不过自己老是忘,干脆写下来吧。
当你有一大篇文字,没有换行(或者行宽太宽、太窄),并且段落之间用空行分开, 那么可以使用以下的技巧来重新分行。
:set tw=100 " textwidth,设置文本行宽度 :set fo+=mM " formatoptions,设置自动换行的条件 gggqG
书写代码时要保持良好的代码风格,缩进、注释、空行等东西一个都不能错。 不过这一点很难做到,即使是一个经验丰富的程序员也难免弄错, 更别说新手了。另外,有时阅读别人写得面条代码也是异常头疼。 不过 Perl 提供了 Perl::Tidy 这个工具可以直接将乱七八糟的 Perl代码整理成格式完美的代码。
我用的是 Windows 下的 ActivePerl 5.8, 因此首先要通过 ppm 安装 Perl::Tidy 软件包。安装方法很简单,启动 ppm 之后 s Perl-Tidy 然后 install 就可以了,不再细说。
Linux下的同学们可以直接去 CPAN 下载源代码进行编译。
安装完成后会生成一个 perltidy 命令。Windows版也有这个命令(位于 C:\Perl\bin\perltidy.bat), 当然前提是你将 C:\Perl\bin 加到了你的 PATH 中。
对某个Perl源代码只要运行下面的命令即可:
perltidy foo.pl
整理好格式的代码会保存为 foo.pl.tdy。
我常用的编辑器是 gvim,自然想到如何将这个功能集成到 gVim 中。 方法很简单,建立 perl.vim,内容如下:
" 调用perltidy整理源代码 nnoremap ,pt :%!perltidy<CR> vnoremap ,pt :!perltidy<CR>
然后将 perl.vim 放到 C:\Program Files\Vim\vimfiles\ftplugin 目录下即可。 以后打开perl源代码之后,直接用 ,pt 快捷键或者用 Shift-V 选择之后再用 ,pt 即可整理正在编辑的代码的格式。
2008-2-14更新
为perltidy加上 -t -nola 参数之后,即可使用TAB缩进而不是空格缩进。perl.vim如下:
" 调用perltidy整理源代码 nnoremap ,pt :%!perltidy -t -nola<CR> vnoremap ,pt :!perltidy -t -nola<CR>
xbeta的这篇文章彻底解决了vim在utf-8模式下显示中文字符为半角字符宽度的问题。
在vim中设置 :set encoding=utf-8 后,中文的一些符号会被显示为半角宽度。这时只需
:set ambiwidth=double
即可。感谢xbeta。
首先安装编译工具。
$ sudo apt-get install build-essential $ sudo apt-get install ncurses-dev $ sudo apt-get install xorg-dev $ sudo apt-get install libgtk2.0-dev
然后从 http://www.vim.org 下载 gvim 7.0 的最新源代码 vim-7.0.tar.bz2。
$ wget ftp://ftp.vim.org/pub/vim/unix/vim-7.0.tar.bz2 $ tar xjvf vim-7.0.tar.bz2 $ cd vim70
编译并安装:
$ ./configure --enable-fontset --enable-cscope --enable-gui --enable-multibyte --with-x $ make $ sudo make install
确认安装是否正确:
$ gvim
如果能正常显示 gVim 的界面则说明安装成功。然后删除自带的 vim 6.4。
$ sudo apt-get remove vim vim-common vim-runtime
建立符号链接使其指向 vim 7.0。
$ sudo ln -s vim /usr/local/bin/vi $ sudo ln -s /usr/local/bin/vim /bin/vi
平常使用Vim作为编辑器的人都会有一种特殊的习惯,使得他们使用其他编辑器时觉得很不顺手。ThunderBird是很好用的邮件程序,不过它的编辑器的功能比较弱。这里的方法可以让你使用Vim作为ThunderBird的编辑器。
首先要为ThunderBird安装External Edit插件,通过它可以使用其他程序编辑邮件。重新启动ThunderBird之后,打开“工具→扩展”菜单,选中刚刚安装好的External Edit插件,单击“选项”按钮打开设置界面。
在Text Editor栏里面输入 gvim 所在的位置,例如“"C:\Program Files\Vim\vim70\gvim.exe" -f -c "set encoding=utf-8"”。-f 参数使得 Vim 在编辑结束之前不返回ThunderBird,这样ThunderBird才能正常接收到Vim编辑的内容。注意要选中下面的“This editor handles Unicode”选项。然后关闭该对话框,回到Thunderbird中,新建邮件,然后在编辑邮件的界面的工具栏中单击右键选择“自定义”,将External Edit按钮拖到工具栏上。
这样我们就做好了设置。以后新建邮件或者回复邮件时,单击工具栏上的External Edit按钮即可打开Vim进行编辑,编辑结束之后退出Vim,编辑内容就会反映到ThunderBird中。
阅读全文 »我使用的Vim是Windows版的Vim6.2。下面是我用到的 _vimrc 和颜色配置文件。
阅读全文 »
本文参考了vim官方网站的文档。为了查找方便起见,文中的技巧编号沿用原文档中的编号。
1. 使用 * 键可以向后搜索光标所在位置的单词。反之,使用 # 键可以向前搜索光标所在位置的单词。第一次使用 * 或者 # 进行搜索之后,则可以使用 N 或 Shift-N 继续进行搜索。另外,如果设置了hlsearch选项(:set hlsearch)的话,那么使用 * Shift-N 则可以标记当前的单词为高亮显示。
2. 经常会遇到这样的情况,就是在命令行上输入含有一个长长的路径的命令 vi /home/username/linux/src/dir1/dir2/dir3/srcfile.c,编辑结束之后发现需要编辑同一目录下的另一个文件,这时不得不在vi中重新输入长长的路径。而将下面的脚本放在vimrc文件(Unix下为~/.vimrc,Windows下为_vimrc)中即可快速输入路径:
" Edit another file in the same directory as the current file
" uses expression to extract path from current file's path
" (thanks Douglas Potts)
if has("unix")
map ,e :e <c -R>=expand("%:p:h") . "/" <cr>
else
map ,e :e <c -R>=expand("%:p:h") . "\" <cr>
endif
这样编辑完第一个文件之后,在vi中输入 ,e ,然后就可以利用Tab键进行自动补齐了。
阅读全文 »/cr></c></cr></c
