2008-07
08

毋庸多言,在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相比一点也不逊色。

vimPerl意义
**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居然还支持环视和固化分组的功能,强大,赞一个 :D 关于环视的解释请参考Yurii的《精通正则表达式》一书吧。

vimPerl意义
\@=(?=顺序环视
\@!(?!顺序否定环视
\@<=(?<=逆序环视
\@<!(?<!逆序否定环视
\@>(?>固化分组
\%(atom\)(?:非捕获型括号

和perl稍有不同的是,vim中的环视和固化分组的模式的位置与perl不同。 例如,查找紧跟在 foo 之后的 bar,perl将模式写在环视的括号内, 而vim将模式写在环视的元字符之前。

# Perl的写法
/(?<=foo)bar/

# vim的写法
/\(foo\)\@<=bar

参考

vim的帮助文件非常有用,关于正则表达式可以参考以下的内容。

:h pattern
:h magic
:h perl-patterns

2008-01
23

很短很好用,不过自己老是忘,干脆写下来吧。

当你有一大篇文字,没有换行(或者行宽太宽、太窄),并且段落之间用空行分开, 那么可以使用以下的技巧来重新分行。

:set tw=100         " textwidth,设置文本行宽度
:set fo+=mM         " formatoptions,设置自动换行的条件
gggqG

2007-10
01

书写代码时要保持良好的代码风格,缩进、注释、空行等东西一个都不能错。 不过这一点很难做到,即使是一个经验丰富的程序员也难免弄错, 更别说新手了。另外,有时阅读别人写得面条代码也是异常头疼。 不过 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>

2007-05
14

xbeta这篇文章彻底解决了vim在utf-8模式下显示中文字符为半角字符宽度的问题。

在vim中设置 :set encoding=utf-8 后,中文的一些符号会被显示为半角宽度。这时只需

:set ambiwidth=double

即可。感谢xbeta。


2006-09
18

首先安装编译工具。

$ 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

2006-06
23

平常使用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中。

阅读全文 »
2005-03
11

我使用的Vim是Windows版的Vim6.2。下面是我用到的 _vimrc 和颜色配置文件。
阅读全文 »


2004-10
12

本文参考了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

阅读全文 »