Vim 中使用正则表达式
经常在网上看到有人抱怨 Vim 的正则表达式太奇怪,无法接受。我倒是觉得 Vim 的正则表达式比较容易理解。可能是因为我最早接触的正则表达式就是 Vim 的正则表达式吧,正好借此机会整理下 Vim 的正则表达式相关的内容。
首先,在哪些情况下会用到正则表达式?
使用正则表达式的命令最常见的就是 /
和 ?
命令。其格式如下:
/正则表达式
?正则表达式
另一个很有用的命令就是 :s
(替换)命令,将第一个//
之间的正则表达式替换成第二个//
之间的字符串。
:s/正则表达式/替换字符串/选项
在学习正则表达式时可以利用 / 命令来练习。
元字符
元字符 | 说明 |
---|---|
. |
匹配任意字符 |
[abc] |
匹配方括号中的任意一个字符。可以使用 - 表示字符范围,如[a-z0-9] 匹 配小写字母和阿拉伯数字。 |
\d |
匹配阿拉伯数字,等同于[0-9] 。 |
[^abc] |
在方括号内开头使用^符号,表示匹配除方括号中字符之外的任意字符。 |
\d |
匹配阿拉伯数字,等同于[0-9]。 |
\D |
匹配阿拉伯数字之外的任意字符,等同于[^0-9]。 |
\x |
匹配十六进制数字,等同于[0-9A-Fa-f]。 |
\X |
匹配十六进制数字之外的任意字符,等同于[^0-9A-Fa-f]。 |
\w |
匹配单词字母,等同于[0-9A-Za-z_]。 |
\W |
匹配单词字母之外的任意字符,等同于[^0-9A-Za-z_]。 |
\t |
匹配<TAB>字符。 |
\s |
匹配空白字符,等同于[ \t]。 |
\S |
匹配非空白字符,等同于[^ \t]。 |
如果需要查找一些特殊字符,如 *
、.
、/
等,可以在这些字符前面添加 \
,表示这些不是元字符,而是普通字符。比如:\/d
匹配的是 /d
这两个字符,而不是匹配任意数字。
表示数量的元字符
元字符 | 说明 |
---|---|
* |
匹配0-任意个 |
\+ |
匹配1-任意个 |
\? |
匹配0-1个 |
\{n,m} |
匹配n-m个 |
\{n} |
匹配n个 |
\{n,} |
匹配n-任意个 |
\{,m} |
匹配0-m个 |
表示位置的符号
元字符 | 说明 |
---|---|
$ |
匹配行尾 |
^ |
匹配行首 |
\< |
匹配单词词首 |
\> |
匹配单词词尾 |
使用示例
命令 | 描述 |
---|---|
/char\s\+[A-Za-z_]\w*; |
查找所有以char开头,之后是一个以上的空白,最后是一个标识符和分号 |
/\d\d:\d\d:\d\d |
查找如 17:37:01 格式的时间字符 |
:g/^\s*$/d |
删除只有空白的行 |
:s/\<four\>/4/g |
将所有的 four 替换成 4,但是 fourteen 中的 four 不替换 |
替换变量
在正规表达式中使用 \(
和 \)
符号括起正规表达式,即可在后面使用\1
、\2
等变量来访问 \(
和 \)
中的内容。
使用示例
命令 | 描述 |
---|---|
/\(a\+\)[^a]\+\1 |
查找开头和结尾处a的个数相同的字符串,如 aabbbaa,aaacccaaa,但是不匹配 abbbaa |
:s/\(http:\/\/[-a-z\._~\+%\/]\+\)/<a href="\1">\1<\/a>/ |
将 url 替换为<a href="http://url">http://url</a>的格式 |
:s/\(\w\+\)\s\+\(\w\+\)/\2\t\1 |
将 data1 data2 修改为 data2 data1 |
函数式
在替换命令 :s/{pattern}/{string}/[flags]
中可以使用函数表达式来书写替换内容,格式为
:s/替换字符串/\=函数式
在函数式中可以使用 submatch(1)
、submatch(2)
等来引用 \1
、\2
等的内容,而submatch(0)
可以引用匹配的整个内容。
使用例
:%s/\<id\>/\=line(".")
将各行的 id 字符串替换为行号
:%s/^\<\w\+\>/\=(line(".")-10) .".". submatch(1)
将每行开头的单词替换为 (行号-10).单词 的格式,如第11行的 word 替换成 1. word
与 Perl 正则表达式的区别
Vim语法 | Perl语法 | 含义 |
---|---|---|
\+ |
+ |
1-任意个 |
\? |
? |
0-1个 |
\{n,m} |
{n,m} |
n-m个 |
\( 和 \)
|
( 和 )
|
分组 |
贪婪模式和非贪婪模式
在 Vim 里,默认是贪婪模式,即 a.*b
会尽可能多滴匹配字符,在 ahdbjkbkls
中匹配 ahdbjkb
而不是 ahdb
。
如果是非贪婪的,可以使用 \{-}
代替 *
,即 a.\{-}b
匹配 ahdb
而不是 ahdbjkb
。
这篇文章后面会持续更新,若发现有误的地方,请在评论区留言。
欢迎加入我们的 QQ 群,与 vimer 一起交流更多的 vim 使用技巧: 755208473