正则表达式是一个包含运算符和运算字符串的表达式,用来匹配特定规则的文本正则表达式简称为表达式.匹配模式或者模式,它们可以互换。Shell的正则表达式与grep.sed.Awk是不同的。
一.正则分类
许多程序设计语言都支持利用正则进行字符串操作。由于起源于unix系统,因此很多语法规则一样的。但是随着逐渐发展,后来扩展出以下几个类型。
1.PREs/Perl RE/POSIX RE
正则从Perl衍生出一个显赫的流派,叫做Perl Compatible Regular Expression,\d.\w.\s就是这个流派的特征。
下面表格列出基本的正则功能在常用GNU工具中的表示法。
PCRE记法 | vi/vim | grep | awk | sed |
* | * | * | * | * |
+ | \+ | \+ | + | \+ |
? | \= | \? | ? | \? |
{m,n} | \{m,n} | \{m,n\} | {m,n} | \{m,n\} |
\b * | \< \> | \< \> | \< \> | \y \< \> |
(…|…) | \(…\|…\) | \(…\|…\) | (…|…) | (…|…) |
(…) | \(…\) | \(…\) | (…) | (…) |
\1 \2 | \1 \2 | \1 \2 | 不支持 | \1 \2 |
注:PCRE中\b表示“单词起始或结束”,Linux工具中\<匹配“单词起始”,\>匹配“单词结束”,sed中\y同时匹配这两个位置。
2.BREs/Basic Regular Expression
grep.vi.sed都属于BRE这一派,是因为这些工具的诞生时间很早,之前这些元字符可能并没有特殊的含义;为保证向后兼容,元字符(.).{.}必须\转义之后才具有特殊含义。
()可用来定义操作符的范围和优先度, (grand)?father匹配father和grandfather。 |
()+为扩展正则里的特殊符号,普通正则需要转义。 echo "abcabc" | grep "\(abc\)\+" echo "abcabc" | grep -E "(abc)+" |
{}和|也是扩展的正则,sed,grep使用时需加\转义,如god|bon匹配单词god或bon |
<>不属于扩展正则,但是通过使用\转义可匹配单词边界,sed.grep.awk等都需转义。 |
3.EREs/Extended Regular Expression(不兼容BRE)
egrep.awk则属于ERE这一派 (其实,现在的BRE和ERE在功能上并没有什么区别,主要的差异是在元字符的转义)。
流派 | 说明 | 工具 |
GNU BRE | (.).{.}.+.?.|都必须转义使用 | GNU grep.GNU sed |
GNU ERE | 元字符不必转义,+.?.(.).{.}.|可直接使用,支持\1.\2 | grep –E.GNU awk |
二、 Linux 中常用文本工具与正则的关系
1.grep , egrep 正则特点(按行处理)
①grep支持:BREs.EREs.PREs | ②egrep支持:EREs.PREs |
grep不跟参数表示使用 ”BREs“ grep ”-E" 要使用 “EREs“ grep “-P" 表示使用 “PREs" | egrep 不跟参数表示要使用 “EREs” egrep “-P" 表示要使用 “PREs" |
2.sed 正则特点(按行处理): 默认BRE, sed “-r”使用ERE
3.Awk(gawk)正则特点(对列进行操作) 支持EREs
三.Regular Expression,RegEx,描述某种规则的表达式
1.POSIX RE元字符(用于方括号之外, \*——*)
^Jack——以Jack开头 123$——$表示在尾部 |
. 1个。 如data\...代表data.后接2个字符, .T.代表3个字符是间是T + 1个.多个 如goo+gle可匹配google.gooogle.goooogle等; * 0个.多个 如xy*——x,x*(*左邻字符出现0个及0个以上)。 ? 0个.1个 如colou?r可匹配color或者colour; xy?——x,xy ^.*anonymous .*等价于1乘于*等价于*等价于0个.多个字符 ( )*$ 匹配结尾处有一个或多个空格的行 $grep -c '^$' ch04 统计空格数 $grep -c '^ *$' ch04 匹配空行 |
sed -n‘s/\(Ha\)/\1ha/p’ dataf3 \(...\)把符合的字符暂存起来\1,\n调用 |
2.POSIX RE元字符(用于方括号之内)
[^0-9],[^A-Z],[^a-zA-Z],[^a-zA-Z0-9]——^代表“非/不是”之意 |
[Ss]ame,[A-Z],[a-z],[0-9]——代表字符串行中长度为1的一个字符 |
[\,]——逗号 |
四.posix字符类 (用于GNU BRE,GNU ERE,PRE)
POSIX在BRE与EERE基础上加入了如下括号字符组的字符。
[:punct:] | 标点符号 | [][!"#$%&'()*+,./:;<=>?@\^_`{|}~-] |
[:alnum:] | 字母和数字 | [a-zA-Z0-9] |
[:lower:] | 小写字母 | [a-z] |
[:upper:] | 大写字母 | [A-Z] |
[:alpha:] | 字母 | [a-zA-Z] |
[:digit:] | 数字 | [0-9] |
[:blank:] | 空格字符和制表符 | [ \t] |
[:space:] | 空白,含空格.制表.换页等 | [ \t\r\n\v\f] |
[:graph:] | 既能看见又能打印的字符 | [\x21-\x7E] |
[:cntrl:] | 控制字符 | [\x00-\x1F\x7F] |
[:print:] | [:graph:]+空白,可打印字符 | [\x20-\x7E] |
[:xdigit:] | 十六进制字符 | [A-Fa-f0-9] |
[:ascii:] | ASCII字符 | [\x00-\x7F] |
以上这些字符类,如[:alnum:]是A-Za-z0-9的另一表达方式。为使用这种字符类,必须使用另一对括号进行将其标识为一正则。例如,A-Za-z0-9本并不是正则,但[A-Za-z0-9]是。
同样的,[:alnum:]应写成[[:alnum:]]:形式一依赖于ASCII字符编码,形式二可在该类中表示来自其他语言的字符。
#cat file: a1 B222 cccc |
要在awk中开启支持posix类字符,需要多加一对中括号比如 awk '/[[:lower:]]/' file //过滤掉了大写的B的行,awk本身就支持扩展正则的 a1 cccc |
如果要过滤一个小写字母开头后面是数字的行呢就可这样表达 #awk '/[[:lower:]][0-9]+/' file a1 |
精确范围类似x\{m,n\}时需要开启posix支持 #awk --posix '/[[:lower:]][0-9]{1,3}$/' file a1 #awk --re-interval '/[[:lower:]][0-9]{1,2}$/' file a1 |
五.8个你应该了解的正则表达式
1.匹配用户名:/^[a-z0-9_-]{3,16}$/
2.匹配密码:/^[a-z0-9_-]{6,18}$/
3.匹配一个Hex值:/^#?([a-f0-9]{6}|[a-f0-9]{3})$/
4.匹配一个Slug:/^[a-z0-9-]+$/
5.匹配一个Email:/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/
6.匹配一个URL:/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/
7.匹配IP地址:/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
8.匹配HTML Tag: /^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$