【Linux】正则表达式
正则表达式是一种可供Linux工具过滤文本的自定义模板,Linux工具(如sed、gawk)会在读取数据时使用正则表达式对数据进行模式匹配。
正则表达式使用元字符来描述数据流中的一个或多个字符。它是由正则表达式引擎实现的。正则表达式引擎是一种底层软件,负责解释正则表达式并用这些模式进行文本匹配。
最流行的正则表达式引擎有两种:
POSIX基础正则表达式(basic regular expression,BRE)引擎;
POSIX扩展正则表达式(extended regular expression,ERE)引擎。
一、BRE模式
最基本的BRE模式是匹配数据流中的文本字符。
1、普通文本
正则表达式匹配的第一条原则:区分大小写。
正则表达式中也可以使用空格和数字:
2、特殊字符
正则表达式能识别的特殊字符如下:
* [] ^ $ {} \ + ? | ()
如果要将某个特殊字符视为普通字符,则必须用反斜线(\)将其转义。
# 匹配文本中的美元符号$
sed -n '/\$/p' test1.txt
转义反斜线(\):
正斜线(/) 虽然不属于正则表达式中的特殊字符,但也需要进行转义,否则会报错。
3、锚点字符
有两个特殊字符可以用来将正则表达式模式锁定在数据流中的行首或者行尾,这两个特殊字符被称为锚点字符。
锚定行首
脱字符(^)可以指定位于数据流中文本行行首的模式,如果模式出现在行首之外的其它地方,则正则表达式无法匹配。
使用脱字符时必须将其置于正则表达式之前。
如果将脱字符放在正则表达式开头之外的位置,sed就会将其视为普通字符进行匹配。
如果只是匹配脱字符,则不用进行转义。
如果要匹配脱字符及其它文本,则需要将脱字符进行转义。
锚定行尾
特殊字符美元符号($)定义了行尾锚点。将其放在正则表达式之后则表示数据行必须以该模式结尾。
组合锚点
查找只含有特定文本模式的数据行。
将两锚点直接组合在一起,之间不加任何文本,可以过滤出数据流中的空行。
如下所示,指定的正则表达式会查找行首和行尾之间什么都没有的那些行,由于空行在两个换行符之间没有文本,所以正好被匹配到。
这是一种从文本中删除空行的一种不错的方法。
sed '/^$/d' test1.txt
4、点号字符
点号字符匹配除换行符以外的任意单个字符,它必须匹配一个字符。
5、字符组
可以在正则表达式中定义用来匹配某个位置的一组字符。如果字符组中的某个字符出现在了数据流中,那就匹配成功。
方括号用于定义字符组,在方括号中加入希望出现在该字符组中的所有字符,就可以在正则表达式中像其它字符一样使用字符组了。
不确定某个字符的大小写时:
在单个正则表达式中可以使用多个字符组:
字符组中也可以使用数字:
6、排除型字符组
可以反转字符组的作用,即匹配字符组中没有的字符。只需在字符组的开头添加脱字符即可。
如下所示,匹配除c或h之外的任何字符以及文本模式。其中空格也能被匹配到。
7、区间
可以使用单连字符在字符组中表示字符区间。
还可以在字符组内指定多个不连续的区间。
如下所示,指定的范围是1到4个7到9。
8、特殊字符组
BRE有一些特殊的字符组。
[[:alpha:]] | 匹配任意字母字符,无论是大写还是小写 |
[[:alnum:]] | 匹配任意字母数字字符,0~9,A~Z或a~z |
[[:blank:]] | 匹配空格或制表符 |
[[:digit:]] | 匹配0~9中的数字 |
[[:lower:]] | 匹配小写字母a~z |
[[:upper:]] | 匹配大写字母A~Z |
[[:print:]] | 匹配任意可打印字符 |
[[:punct:]] | 匹配标点符号 |
[[:space:]] | 匹配任意空白字符:空格、制表符、换行符、分页符、回车符、垂直制表符 |
这些特殊字符组的用法和普通字符组的用法一样
9、星号*
匹配次数大于等于0次。
这个特殊符号常用于处理有常见拼写错误或在不同语言中有拼写变化的单词。
点号字符与星号字符组合起来,能够匹配任意数量的任意字符,一般用在数据流中两个可能相邻或不相邻的字符串之间。
星号还能用于字符组,指定可能在文本中出现0次或多次的字符组或字符区间。
不能出现字符组以外的其它字符,否则就无法匹配到。
二、ERE模式
gawk支持ERE模式,但sed不支持。前者可以使用大多数扩展的正则表达式符号,并能提供一些sed所不具备的额外过滤功能,但正因为如此,也使得gawk在处理数据时较慢。
1、问号
匹配0次或1次,不能匹配超过1次的多次。
问号也可以和字符组一起使用:如果字符组中的字符出现了0次或1次,就能匹配上;如果两个字符都出现或者其中一个出现了两次及以上,就不能匹配上。