正则表达式(介绍,特殊字符,POSIX字符)
处理海量日志对每一个运维来说都非常的头疼,日志分析我们首先需要把需要的数据从海量的日志中匹配出来,降低数据量,然后在分析这些日志。那么从海量的日志中把我们需要的日志找出来就需要我们写一个公式来匹配,那么如何才能写一个这样的公式呢?
正则表达式其实就是通过给定的符号生成一个字符串匹配的公式,通过该公式把需要的数据匹配出来。
比如
- 匹配正确的IP地址
- 匹配正确的e-mail地址
一、正则表达式介绍
正则表达式(Regular Expression、regex或regexp,缩写为RE),也译为正规表示法、常规表示法,是一种字符模式,用于在查找过程中匹配指定的字符。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。
正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。
支持正则表达式的程序如:locate |find| vim| grep| sed |awk
正则表达式是一个三方产品,被常用计算机语言广泛使用,比如:shell、PHP、python、java、js等!
shell中也支持正则表达式,但不是所有的命令都支持,常见的命令中只有grep,sed,awk命令
简单来说,就是使用它提供的特殊字符,生成一个公式,用这个公式从海量的数据中筛选出想要的数据
二、正则表达式特殊字符
1、定位符使用技巧:同时锚定开头和结尾,做精确匹配;单一锚定开头或结尾或者不锚定的,做模糊匹配。
定位符 | 说明 |
---|---|
^ | 锚定开头 ^a 以a开头 默认锚定一个字符 |
$ | 锚定结尾 a$ 以a结尾 默认锚定一个字符 |
egrep和grep -e 相等
(centos7得使用-E)
精确匹配:
[root@CentOs shell]# egrep "^ac$" test.sh
ac
[root@CentOs shell]#
模糊匹配
2、配符:匹配字符串
匹配符 | 说明 | |
---|---|---|
. | 匹配除回车以外的任意一个字符 | |
( ) | 字符串分组 | |
[ ] | 定义字符类,匹配括号中的一个字符 | |
[ ^ ] | 表示否定括号中出现字符类中的字符,取反。 | |
\ | 转义字符 | |
| | 或 |
(1)“.”字符测试
(2)中括号字符测试
(3)转义字符测试
(4)小括号与或测试
小括号分组
3、限定符:对前面的字符或者(字符串)出现的次数做限定说明
限定符 | 说明 |
---|---|
* | 某个字符之后加星号表示该字符不出现或出现多次 a* (ab)* |
? | 与星号相似,但略有变化,表示该字符出现一次或不出现 |
+ | 与星号相似,表示其前面字符出现一次或多次,但必须出现一次 |
{n,m} | 某个字符之后出现,表示该字符最少n次,最多m次 |
{m} | 正好出现了m次 |
(1)*号限定符(出现多次或不出现)
[root@CentOs shell]# egrep "^ab*c$" test.sh (中间可以有一个或多个b)
ac
abbc
abbbc
abbbbbc
abc
[root@CentOs shell]#
(2)?号限定符(出现一次或不出现)
[root@CentOs shell]# egrep "^ab?c$" test.sh
ac
abc
[root@CentOs shell]#
(3)+号限定符(至少出现一次)
[root@CentOs shell]# egrep "^ab+c$" test.sh
abbc
abbbc
abbbbbc
abc
[root@CentOs shell]#
(4)大括号限定出现的次数
[root@CentOs shell]# egrep "^ab{3}c$" test.sh
abbbc
[root@CentOs shell]#
[root@CentOs shell]# egrep "^ab{2,5}c$" test.sh
abbc
abbbc
abbbbbc
[root@CentOs shell]#
三、正则表达式POSIX字符
posix字符一次只匹配一个范围中的一个字节
特殊字符 | 说明 |
---|---|
[:alnum:] | 匹配任意字母字符0-9 a-z A-Z |
[:alpha:] | 匹配任意字母,大写或小写 |
[:digit:] | 数字 0-9 |
[:graph:] | 非空字符( 非空格控制字符) |
[:lower:] | 小写字符a-z |
[:upper:] | 大写字符A-Z |
[:cntrl:] | 控制字符 |
[:print:] | 非空字符( 包括空格) |
[:punct:] | 标点符号 |
[:blank:] | 空格和TAB字符 |
[:xdigit:] | 16 进制数字 |
[:space:] | 所有空白字符( 新行、空格、制表符) |
注意:
注意[[ ]] 双中括号的意思: 第一个中括号是匹配符[] 匹配中括号中的任意一个字符,第二个[]是格式 如[:digit:]
测试:
[root@CentOs shell]# egrep "^a[[:alnum:]]c$" test.sh (中间一个空格都不能有)
acc
abc
aZc
a3c
[root@CentOs shell]#
[root@CentOs shell]# egrep "^a[[:upper:]]c$" test.sh
aZc
[root@CentOs shell]#
可以与前面搭配使用
[root@CentOs shell]# egrep "^a[[:alnum:]]*c$" test.sh
ac
abbc
abcc
aabbcc
abbbc
abbbbbc
acc
abc
aZc
aAAAAc
a3c
abbbbbbbc
[root@CentOs shell]#
匹配ip地址:
[root@CentOs shell]# egrep '^((25[0-5]|2[0-4][[:digit:]]|[01]?[[:digit:]][[:digit:]]?).){3}(25[0-5]|2[0-4][[:digit:]]|[01]?[[:digit:]][[:digit:]]?)$' --color ip.txt
1.1.1.1
192.168.11.0
[root@CentOs shell]#
经过我一上午的测试,发现 egrep "^a.a$" test.sh 这种情况下匹配不出字符,不知道为啥,怀疑是中间的那个“.”的问题,但是首尾字符不一致,中间加上“.”也能匹配出来,很困惑~
(后来终于解决了这个问题,是源文件里没有这种类型的字符~我真呆)