正则表达式¶
在 Vim 中最常用到正则表达式的莫过于搜索和替换命令。
先来看一个现实的问题,如果在 Vim 中,将正则表达式中定义的大量元字符原封不动地引用(就像 perl),势必会给使用正常编辑功能的人造成困扰。比如 /foo(1) 命令,按照正则表达式来理解会是搜索 foo1 字符串。而在大多数人编辑器中应该是搜索 foo(1) 字符串。
Vim 毕竟是一个编辑器,于是在 Vim 中规定,正则表达式的元字符必须用反斜杠进行转义(和大多数正则表达式对转义符的定义正好相反)。如果上面的例子要用正则表达式搜索,就应写成 /foo\(1\) 。但是,像 . * 这种极其常用的元字符,都加上反斜杠就太麻烦了。而且,众口难调,有些人喜欢用正则表达式,有些人不喜欢用...
为了解决这个问题,Vim 设置了 magic 变量。简单地说,magic 就是设置哪些元字符要加反斜杠哪些不用加的。 简单来说:
- magic (\m):除了
$ . * ^之外其他元字符都要加反斜杠 - nomagic (\M):除了
$ ^之外其他元字符都要加反斜杠
这个设置也可以在正则表达式中通过 \m \M 开关临时切换。 \m 后面的正则表达式会按照 magic 处理, \M 后面的正则表达式按照 nomagic 处理,并忽略实际的 magic 设置。
例如:
/\m.* # 查找任意字符串
/\M.* # 查找字符串 .* (点号后面跟个星号)
另外还有两个包含全部的命令。
\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}$
Vim 默认设置是 magic,也推荐大家都使用 magic 的设置。有特殊需求时,直接通过 \v \m \M \V 中的一种定义即可。
Vim 中设定 magic 变量:
:set magic " 设置magic
:set nomagic " 取消magic
:h magic " 查看帮助
基本元素¶
本文下面使用的字符都是默认(magic)模式下的,在其他模式下请自行转义。
常用的元字符¶
| 元字符 | 意义 |
|---|---|
| . | 匹配任意一个字符 |
| [abc] | 匹配方括号中的任意一个字符。也可以用 - 表示范围 |
| [a-z0-9] | 匹配小写字母和阿拉伯数字中的一个字符 |
| [^abc] | 匹配除方括号中字符之外的任意一个字符 |
| \(abc\) | 分组匹配,将 abc 放入 1 中 |
| \d | 匹配阿拉伯数字,等同于 [0-9] |
| \D | 匹配阿拉伯数字之外的任意字符,等同于 [^0-9] |
| \x | 匹配十六进制数字,等同于 [0-9A-Fa-f] |
| \w | 匹配单词字母,等同于 [0-9A-Za-z_] |
| \W | 匹配除单词字母之外的任意字符,等同于 [^0-9A-Za-z_] |
| \t | 匹配 <TAB> 字符 |
| \s | 匹配空白字符,等同于 [ \t] |
| \S | 匹配非空白字符,等同于 [^ \t] |
| \a | 匹配所有的字母字符。等同于 [a-zA-Z] |
| \l | 匹配小写字母 [a-z] |
| \L | 匹配非小写字母 [^a-z] |
| \u | 匹配大写字母 [A-Z] |
| \U | 匹配非大写字幕 [^A-Z] |
注解
用 \( 和 \) 进行分组匹配,在分组后面可以使用 \1 、 \2 等变量来访问分组的内容(注意:\0 表示匹配的所有内容),最多保存一行中的 9 个分组。这种形式实际上是将分组中的内容保存到特殊的空间(保留缓冲区)中。
# 原字符串 That or this
# 替换后的字符串 this or That
:%s/\(That\) or \(this\)/\2 or \1/
量词¶
| 元字符 | 意义 |
|---|---|
| * | 匹配 0 个或多个 |
| \+ | 匹配1个或多个(匹配优先) |
| \? 或 \= | 0 个或 1 个,\? 不能在 ? 命令中使用 |
| \{n,m} | 匹配 n 个到 m 个 |
| \{n,} | 匹配最少 n 个 |
| \{,m} | 匹配最多 m 个 |
| \{n} | 匹配 n 个 |
注解
用于限定数量的元字符不仅可用于字符,也可以用于分组等模式。举例如下:
\(123\)\{2} # 匹配 123123
表示位置的符号¶
| 元字符 | 意义 |
|---|---|
| $ | 匹配行尾,如 tail$ 只匹配位于一行结尾处的 tail |
| ^ | 匹配行首,如 ^head 只匹配位于一行开头处的 head |
| \< | 匹配以某些字符开头的单词,\<ac 只匹配以 ac 开头的单词,如 action |
| \> | 匹配以某些字符结尾的单词,ad\> 只匹配以 ac 开头的单词,如 head |
非贪婪匹配¶
正则表达式中有贪婪匹配和非贪婪匹配两种,Vim 默认开启贪婪匹配。如果想使用非贪婪匹配,可以使用 \{-} 代替 * 、 + 等量词。
字符串:ahdbjkbkls
a.*b # 匹配 ahdbjkb
a.\{-}b # 匹配 ahdb