Linux正则匹配详解
前言
对于正则表达式,相信很多人都知道,但是很多人的第一感觉就是难学,因为看第一眼时,觉得完全没有规律可寻,而且全是一堆各种各样的特殊符号,完全不知所云。
其实只是对正则不了解而以,了解了你就会发现,原来就这样啊正则所用的相关字符其实不多,也不难记,更不难懂,唯一难的就是组合起来之后,可读性比较差,而且不容易理解,本文旨在让大家对正则有一个基本的了解,能看得懂简单的正则表达式,写得出简单的正则表达式,用以满足日常开发中的需求即可。
0\d{2}-\d{8}|0\d{3}-\d{7} 先来一段正则,如果你对正则不了解,是不是完全不知道这一串字符是什么意思?这不要紧文章会详细解释每个字符的含义的。
什么是正则表达式
正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去匹配符合规则的字符。
正则字符简单介绍
元字符介绍
|
|
几种反义
|
|
量词
贪婪(贪心),如"*“字符 贪婪量词会首先匹配整个字符串,尝试匹配时,它会选定尽可能多的内容,如果失败则回退一个字符,然后再次尝试回退的过程就叫做回溯,它会每次回退一个字符,直到找到匹配的内容或者没有字符可以回退。相比下面两种贪婪量词对资源的消耗是最大的.
懒惰(勉强),如 “?” 懒惰量词使用另一种方式匹配,它从目标的起始位置开始尝试匹配,每次检查一个字符,并寻找它要匹配的内容,如此循环直到字符结尾处.
占有,如”+" 占有量词会覆盖事个目标字符串,然后尝试寻找匹配内容,但它只尝试一次,不会回溯,就好比先抓一把石头,然后从石头中挑出黄金.
“"(贪婪): 重复零次或更多,例如"aaaaaaaa”,匹配字符串中所有的a,正则: “a",会出到所有的字符"a”
“+"(懒惰): 重复一次或更多次,例如"aaaaaaaa” 匹配字符串中所有的a,正则: “a+",会取到字符中所有的a字符,“a+“与"a*“不同在于”+“至少是一次而”*” 可以是0次.
“?"(占有): 重复零次或一次,例如"aaaaaaaa” 匹配字符串中的a,正则: “a?",只会匹配一次,也就是结果只是单个字符a.
“{n}": 重复n次,例如从"aaaaaaaa” 匹配字符串的a 并重复3次,正则: “a{3}“结果就是取到3个a字符"aaa”;
“{n,m}": 重复n到m次,例如正则 “a{3,4}” 将a重复匹配3次或者4次,所以供匹配的字符可以是三个"aaa"也可以是四个"aaaa” 正则都可以匹配到.
“{n,}": 重复n次或更多次,与{n,m}不同之处就在于匹配的次数将没有上限,但至少要重复n次 如 正则"a{3,}",a至少要重复3次
懒惰限定符
“?": 重复任意次,但尽可能少重复,例如"acbacb”,正则"a.?b” 只会取到第一个"acb” 原本可以全部取到但加了限定符后,只会匹配尽可能少的字符,而"acbacb"最少字符的结果就是"acb”.
“+?": 重复1次或更多次,但尽可能少重复,与上面一样,只是至少要重复1次
“??": 重复0次或1次,但尽可能少重复,例如 “aaacb” 正则 “a.??b” 只会取到最后的三个字符"acb”
“{n,m}?": 重复n到m次,但尽可能少重复,例如 “aaaaaaaa” 正则 “a{0,m}” 因为最少是0次所以取到结果为空
“{n,}?": 重复n次以上,但尽可能少重复,例如 “aaaaaaa” 正则 “a{1,}” 最少是1次所以取到结果为"a”.
grep 正则表达式
grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。
Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。
grep常用用法
|
|
sed 正则表达式
sed 用法
|
|
awk 正则表达式
awk 语法
|
|
awk可以读取后接的文件,也可以读取来自前一命令的标准输入,它分别扫描输入数据的每一行,查找当前扫描行中pattern是否匹配。如果匹配,则进行后续动作action。如果pattern不匹配或action部分处理完毕,则继续处理下一行,直到结束。
|
|
其中BEGIN为处理文本前的操作,一般用于改变FS,OFS,RS,ORS等,BEGIN部分完成之后,awk读取第一行输入,并将第一行的数据填入$0,$1,$2,..,$n,NR,NF等变量,然后进入正式处理阶段,待所有行处理完毕之后,进入END部分,END一般用于总结,打印报表等。
正式处理是一个内建的循环,每一次循环读取一行数据(默认RS为换行符),pattern{…}部分可以有多个,它可以使用正则匹配/RE/,算术运算符>,<,…,逻辑运算符&&,||等,当pattern没有时,也即不需要匹配条件,后面的动作{…}会在每一行都执行.
awk 内置变量
变量 | 用法 |
---|---|
$0 | 当前记录(这个变量中存放着整个行的内容) |
$1-$n | 当前记录的第n个字段,字段间由FS分隔 |
FS | 输入字段分隔符 默认是空格或者\t |
NF | 当前记录的字段个数 就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中 |
FNR | 当前记录数,与NR不同的是,这个值会是各个文件自己的行号 |
RS | 输入的记录分隔符,默认为换行符 |
OFS | 输出字段分隔符,默认为空格 |
ORS | 输出的记录分隔符,默认为换行符 |
FILENAME | 当前输入文件的名字 |
awk运算符合正则匹配
算术运算符
- awk算术运算符:
!=,>,<,>=,<=
逻辑运算符
&&
多个条件且||
多个条件或
正则匹配
- awk使用的RE为扩展正则表达式,匹配格式为/reg/
- 定位行:
- NR==行号
- 用RE: /^Disk/
- 字符串匹配: ~匹配!~不匹配
/reg/
在整行范围内匹配reg,匹配到就执行后续动作!/reg/
整行没匹配到reg,才执行后续的动作$1~/reg/
只在第一字段匹配reg$1!~/reg/
第一个字段不匹配NR >=2
从第二行开始处理
awk 整则可以和比较运算符结合使用,以便处理更复查的匹配
awk技巧
- awk使用的RE为ERE
- 如果在BEGIN中设置了OFS,只有$0有改动OFS才能生效
printf
与print
的区别:printf
不自动打印换行符,print
则自动打印换行符- gsub的返回值并不是替换后的字符串,而是返回替换的次数
- 字符串常量一定用在"“包围起来,否则当做变量使用,如
$1=="ipaaad"
- awk的for循环为
C-Style
即为for()
,区别于shell中的for i in ...
- awk中可以使用多个分隔符,要封装在方括号里,用'‘包围,以防shell对他们进行解释,如
awk -F '[:/t]'
,使用空格,冒号,tab作为分隔符 - next语句: 从输入文件中取得下一个输入行,在awk命令表顶部重新执行命令,一般用于跳过一些特殊的行
- awk匹配多个条件: `awk ‘/kobe/ && /james/’, 这会匹配的同时有kobe和james的行
- FS默认值是
[/t/n]+
,OFS的默认值为空格,RS,ORS的默认值都是换行 - exit语句: 终止AWK程序,但不跳过END语句
{s1;s2;s3;...}
中多个语句用分号隔开if;else if;else
print
后不带任何参数时,相当于print $0
,将会打印整行记录
awk用法
|
|
split 使用
|
|