文章目录
- 一、magic 介绍
- 二、设置 magic
- (一)长效设置
- (二)临时设置
- (三)magic 示例
- 1. 匹配由 3 个以字母 a 开头,以字母 c 结尾,中间是任意一个字符的子串组成的字符串
- (1)very magic 模式下
- (2)magic 模式下
- (3)nomagic 模式下
- (4)very nomagic
- 2. 在一个 CSS 样式文件中查找所有的颜色代码
- (1)magic 模式下
- (2)very magic 模式下
一、magic 介绍
vim 毕竟是个编辑器,正则表达式中包含的大量元字符如果原封不动地引用(像 perl 那样), 势必会给不懂正则表达式的人造成麻烦,比如 /foo(1)
命令, 大多数人都用它来查找foo(1)
这个字符串, 但如果按照常规的正则表达式来解释,被查找的对象就成了 foo1
了。因为在小括号 ()
不是普通的字符,而是有特殊含义的字符,小括号 ()
包裹的内容视为一个整体项,这里小括号只含有 1
,那么就匹配 1
,加上前面的字符串 foo
,那么匹配的字符串就是 foo1
。
于是,vim 就规定,常规的正则表达式的元字符必须用反斜杠进行转义才行, 如上面的例子,如果确实要用常规的正则表达式,就应当写成 /foo\(1\)
。 但是,像 .
、*
这种极其常用的正则表达式元字符,都加上反斜杠就太麻烦了。 而且,众口难调,有些人喜欢用常规的正则表达式,有些人不喜欢用…
为了解决这个问题,vim 设计 magic 这个东西。简单地说, magic 就是用来设置哪些元字符要加反斜杠哪些不用加的工具。
二、设置 magic
(一)长效设置
要在“底行命令模式”下设置 vim 的 magic,设定方法为:
命令 | 说明 |
---|---|
set magic | 设置 magic,除了 $ 、. 、* 、^ 、[ ] 之外其他正则表达式的元字符都要加反斜杠进行转义,否则视为普通的字符,这是 vim 的默认设置 |
set nomagic | 取消 magic,除了 $ 。^ 之外其他元字符都要加反斜杠 |
h magic | 查看帮助 |
(二)临时设置
这个设置也可以在正则表达式中通过 \m
,\M
、\v
、\V
共 4 个开关来临时切换。
设置指令 | 说明 |
---|---|
\m | 表示后面的正则表达式会按照 magic 处理,例如,/\m.*(ktv) ,后面的 (ktv) 是 5 个普通的字符,而不是分组,要当成分组使用,小括号前面要加上转义符号 \ 才行 |
\M | 后面的正则表达式按照 nomagic 处理, 而忽略实际的 magic 设置 |
\v | very magic,意为非常魔幻,又叫模式开关。任何元字符都不用加反斜杠,vim 会自动识别元字符。该模式下,除下划线 _ 、# 、英文字母以及数字之外的所有字符都具有特殊含义 |
\V | very nomagic,意为非常不魔幻,其实就是非常不智能,非常傻的模式,又叫原义开关。任何元字符都必须加反斜杠,任何有特殊含义的字符都必须加反斜杠,否则视为普通字符。该模式下只有反斜杠 \ 具有特殊意义,其它的都是普通字符 |
注:
- 默认设置是 magic,vim 也推荐大家都使用 magic 的设置,在有特殊需要时,直接通过临时设置即可。
- 一个通用的原则是:如果想按正则表达式查找,就用模式开关
\v
,如果想按原义查找文本,就用原义开关\V
。
(三)magic 示例
1. 匹配由 3 个以字母 a 开头,以字母 c 结尾,中间是任意一个字符的子串组成的字符串
(1)very magic 模式下
/\v(a.c){3}$
正则表达式解释:
$
表示行尾,这是个虚拟的概念。{3}
表示前面的字符串要出现 3
次,(a.c)
,小括号包裹的内容作为一个整体,所以小括号的内容整体要出现3次,.
表示任意一个字符,那么像这样的 abcabcabc,adcafcagc 等都可以匹配,只要确保以 a
开头,以 c
结尾,中间任意一个字符所组成的整体出现 3
次就可以了。
(2)magic 模式下
/\m\(a.c)\{3}$
这里使用 \m
,说明除了 $
、.
、*
、^
之外其他正则表达式的元字符都要加反斜杠进行转义,所以小括号、大括号都需要转义 vim 引擎才会视为元字符,大括号可以只转义左边的,右边的 vim 会自动识别,但是小括号则不行,中括号也只要转义左边即可。
如果不进行转义处理,如下所示:
/\m(a.c){3}$
正则表达式解释:
这里使用 \m,说明除了 $
、.
、*
、^
之外其他正则表达式的元字符都要加反斜杠进行转义,否则视为普通的字符,所以这里的小括号、花括号都只是普通字符,只有一个字符 .
属于正则表达式的元字符,它表示任意单个字符,所以这个表达式匹配行尾的 (abc){3}
,(aec){3}
,(a%c){3}
等这样的字符串。
(3)nomagic 模式下
/\M\(a\.c)\{3}$
使用 \M
,那么就只认 $
和 ^
,其它字符一律当成普通字符,所以小括号、大括号、.
这些字符都要转义才能视为元字符。
如果不转义,如下所示:
/\M(a.c){3}$
正则表达式解释:
使用 \M
,那么就只认 $
和 ^
,其它字符一律当成普通字符,字符 .
也只是个普通字符了。所以这个表达式仅匹配行尾的(a.c){3}
。
(4)very nomagic
/\V\(a\.c)\{3}\$
使用 \V
,那么所有的字符都被视为普通字符,所以小括号、大括号、.
、$
都需要转义才能视为元字符。
不转义,如下所示:
/\V(a.c){3}$
正则表达式解释:
使用 \V
,那么所有的字符都被视为普通字符,所以这个表达式可以匹配文本中任意位置的字符串 (a.c){3}$
。
2. 在一个 CSS 样式文件中查找所有的颜色代码
查找如下所示的颜色代码:
a {color: #0000EE;}
body {color: #3c3c3c;}
strong {color: #000;}
需要构造一个正则表达式,用于匹配 1 个 #
字符以及紧随其后的 3 个或 6 个十六进制字符的目标串(包括所有数字以及大写或小写的字母)。
(1)magic 模式下
/#\([0-9a-fA-F]\{6}\|[0-9a-fA-F]\{3}\)
如上所示,magic 下,vim 引擎认为 .
、*
、$
、^
、[
是元字符,其它都是普通字符,所以小括号、大括号、竖线都要转义才能视为元字符。注意小括号的左右括号都要加 \
进行转义,不知道为什么?magic 下不是只认识 .
、*
、$
、^
吗?为什么中括号不要转义呢?
(2)very magic 模式下
/\v#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})
超智能,除了英文字母、数字、下划线、#
以外的字符都是元字符。