任何一个现代编辑器或编程语言,如果不支持正则表达式,则可考虑立刻放弃,因为正则表达式不仅仅只是高效,还有点身份地位象征的意味。
正则表达式指使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。如果用vi而不懂正则表达式,则等于根本不会用。正则表达式是vi处理文本最有力的武器,稍微上点“档次”的编辑器或语言都支持正则表达式。花点时间学习正则表达式是跟普通程序员拉开距离的捷径。
正则表达式至少可以做到以下事情:
注:正则表达式有很多种实现,各版本之间有些诧异,但基础构成方面都是一样的,学习使用的时候要加以区分。
元字符
可理解为关键字或保留字,这些字符做特殊用途
字符 |
解释 |
. |
匹配换行符以外的任意字符 |
^ |
匹配字符串的开始位置 |
$ |
匹配字符串的结束位置 |
* |
匹配前面的子表达式零次或多次,等价于{0,} |
+ |
匹配前面的子表达式一次或多次,等价于{1,} |
|
匹配前面的子表达式零次或一次,等价于{0,1} |
\ |
转义符,将特殊字符进行转义 |
[] |
[abc]字符集合,匹配所包含的任意一个字符 |
|
[^abc]负值字符集合,匹配未包含的任意字符 |
|
[a-z] 字符范围,匹配指定范围内的任意字符 |
() |
两个字符一起使用,用于创建一个用于匹配的子串,也叫分组 |
{} |
{n}匹配确定的n次 |
|
{n,}至少匹配n次,等价于"*" |
|
{n,m}最少匹配n次且最多匹配m次(其中n<=m) |
还有| 交替匹配,符号两边的任意一项
预设字符
字符 |
解释 |
\b |
单词边界,同\< |
\B |
非单词边界,同 \> |
\d |
数字字符,同 [0-9] |
\D |
非数字字符,同[^0-9] |
\s |
空白字符,同 [ \t\n\r\f\v] |
\S |
非空白字符,同 [^\t\n\r\f\v] |
\w |
字母数字字符,同 [a-zA-Z0-9_] |
\W |
非字母数字字符,同 [^a-zA-Z0-9_] |
\t |
Tab,同0x09 |
\r |
回车符,同0x0D |
\n |
换行符,同0x0A |
\f |
换页符 |
\v |
垂直制表符,同ox0b |
\x |
十六进制,例如“x41”匹配“A” |
\u |
Unicode字符。例如,u00A9匹配版权符号 |
POSIX字符类
字符 |
解释 |
[:alnum:] |
匹配任意一个字母或数字字符 |
[:alpha:] |
匹配任意一个字母字符(包括大小写字母) |
[:blank:] |
空格与制表符(横向和纵向) |
[:digit:] |
匹配任意一个数字字符 |
[:lower:] |
匹配小写字母 |
[:upper:] |
匹配大写字母 |
[:punct:] |
匹配标点符号 |
[:space:] |
匹配一个包括换行符、回车等在内的所有空白符 |
[:graph:] |
匹配任何一个可以看得见的且可以打印的字符 |
[:xdigit:] |
任何一个十六进制数(即:0-9,a-f,A-F) |
[:cntrl:] |
任何一个控制字符(ASCII字符集中的前32个字符) |
[:print:] |
任何一个可以打印的字符 |
常用表达式
数字相关
- 正整数
^[1-9]d*$
- 负整数
^-[1-9]d*$
- 整数
^-?[1-9]d*$
- 非负整数(正整数 + 0)
^[1-9]d*|0$
- 非正整数(负整数 + 0)
^-[1-9]d*|0$
- 正浮点数
^[1-9]d*.d*|0.d*[1-9]d*$
- 负浮点数
^-([1-9]d*.d*|0.d*[1-9]d*)$
- 浮点数
^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$
- 非负浮点数(正浮点数 + 0)
^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$
- 非正浮点数(负浮点数 + 0)
^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$
格式检查
- 匹配中文字符
[u4e00-u9fa5]
- 限定只能输入中文字符:
^[u4e00-u9fa5],{0,}$
- 匹配Email地址:
^w+[-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$
- 匹配URL地址:
^http(s)://([w-]+.)+[w-]+(/[w-./?%&=]*)?$
- 匹配国内电话号码:
^((d{3,4})|d{3,4}-)?d{7,8}$
- 匹配国内邮政编码:
[1-9]d{5}(?!d)
- 匹配国内身份证号:
^d{15}|d{18}$
- 匹配首尾空白字符
^s*|s*$
- 匹配Email地址
w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*
- 匹配网址URL
[a-zA-z]+://[^s]*
- 匹配ip地址:
d+.d+.d+.d+
RegularExpressionValidator表单验证
- 只能输入数字:
^[0-9]*$
- 只能输入n位的数字:
^d{n}$
- 只能输入至少n位数字:
^d{n,}$
- 只能输入m-n位的数字:
^d{m,n}$
- 只能输入零和非零开头的数字:
^(0|[1-9][0-9]*)$
- 只能输入有两位小数的正实数:
^[0-9]+(.[0-9]{2})?$
- 只能输入有1-3位小数的正实数:
^[0-9]+(.[0-9]{1,3})?$
- 只能输入非零的正整数:
^+?[1-9][0-9]*$
- 只能输入非零的负整数:
^-[1-9][0-9]*$
- 只能输入长度为3的字符:
^.{3}$
- 只能输入由26个英文字母组成的字符串:
^[A-Za-z]+$
- 只能输入由26个大写英文字母组成的字符串:
^[A-Z]+$
- 只能输入由26个小写英文字母组成的字符串:
^[a-z]+$
- 只能输入由数字和26个英文字母组成的字符串:
^[A-Za-z0-9]+$
- 只能输入由数字、26个英文字母或者下划线组成的字符串:
^w+$
- 匹配账号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
- 验证月数:
^(0?[1-9]|1[0-2])$ 正确格式为:“01”-“09”和“1”“12”
- 验证天数:
^((0?[1-9])|((1|2)[0-9])|30|31)$
在vim中使用正则表达式
基本表达式: [range]s/from/to/[flags]
- range:搜索范围,如果没有指定范围,则作用于但前行。
:1,10s/from/to/ 表示在第1到第10行(包含第1,第10行)之间搜索替换;
:10s/from/to/ 表示只在第10行搜索替换;
:%s/from/to/ 表示在所有行中搜索替换;
:1,$s/from/to/ 同上。
c confirm,每次替换前询问;
e error, 不显示错误;
g globle,不询问,整行替换。如果不加g选项,则只替换每行的第一个匹配到的字符串;
i ignore,忽略大小写。
例子
- 将foo(a,b,c) 改为foo(b,a,c)
:%s/foo(\([^,]*\),\([^,]*\),\([^)]*\))/foo(\2,\1,\3)/g
- 将abcdef abcedg 都替换为 abc asd
:%s/abc.*/abc asd/g
- 删除以数字开头的行
%s/^\d.*$//g
- 删除以[a,b,c]开头的行
:%s/^[a|b|c].*$//g
- 替换windows换行符
:%s/<c-v><c-m>//g
- 将url替换为html链接
:s/\(http:\/\/[-a-z\._~\+%\/]\+\)/<a href="\1">\1<\/a>/
- 将各行的 id 字符串替换为行号
id 123 id 456
:%s/\<id\>/\=line(".")
- 将多个空格替换为1个
:%s/ */ /g
- 删除行尾空格
:%s/ *$//g
- 删除行首空格
:%s/^ *//g
- 删除所有空白行
:g/^\s*$/d
- 删除所有出现有string的行
:g/string/d
- 删除所有不包含string的行
:v/string/d
- 删除所有HTMl标签,保留文本
:%s#<{FNXX==XXFN}\+>##g
- 删除重复行
:%s/^\(.*\)\n\1$/\1/g
- 每行开头加一个空格
:%s/^/ /g
- 修改错误拼写,例如文本中出现了beg,bssg,big都替换成bug
:%s/b[e|s|i].*g/bug/g
- 批量添加注释
:%s/^/#/ 每行开头添加#号
:3,10s/^/#/ 3-10行每行开头添加#号
|