1.定义
正则表达式是你所定义的模式模板(pattern template),Linux工具可以用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉
2. 类型
正则表达式是通过正则表达式引擎(regular expression engine)实现的。正则表达式引擎是
一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。
在Linux中,有两种流行的正则表达式引擎:
POSIX基础正则表达式(basic regular expression,BRE)引擎
POSIX扩展正则表达式(extended regular expression,ERE)引擎
2.1 基础正则表达式
2.1.1 纯文本
最基本的BRE模式是匹配数据流中的文本字符
echo "This is a test" | sed -n '/test/p' # 由于echo语句含单词test,数据流文本能够匹配所定义的正则表达式模式,因此sed编辑器显示了该行
echo "This is a test" | sed -n '/trial/p' # 由于echo语句不含单词trial,数据流文本无法匹配所定义的正则表达式模式,因此sed编辑器输出空白
echo "This is a test" | awk '/test/{print $0}' # 由于echo语句含单词test,数据流文本能够匹配所定义的正则表达式模式,因此awk输出全部语句
echo "This is a test" | awk '/trial/{print $0}' # 由于echo语句不含单词trial,数据流文本无法匹配所定义的正则表达式模式,因此awk输出空白
- 正则表达式模式都区分大小写
- 在正则表达式中,你不用写出整个单词。只要定义的文本出现在数据流中,正则表达式就能
够匹配 - 可以在正则表达式中使用空格和数字,可以创建匹配多个连续空格的正则表达式模式用来查看文本文件中空格。
echo "This is a test" | sed -n '/This/p'
echo "The books are expensive" | sed -n '/book/p'
echo "This is line number 1" | sed -n '/ber 1/p'
2.1.2 特殊字符
- 正则表达式识别的特殊字符包括:
.*[]^${}\+?|()
,如果要用某个特殊字符作为文本字符,就必须使用转义字符(\)
echo "\ is a special character" | sed -n '/\\/p'
echo "3 / 2" | sed -n '///p'
echo "3 / 2" | sed -n '/\//p'
2.1.3 锚字符
- 脱字符(
^
)锁定在行首
脱字符(^
)定义从数据流中文本行的行首开始的模式,脱字符会在每个由换行符决定的新数据行的行首检查模式。
如果将脱字符放到模式开头之外的其他位置,那么它就跟普通字符一样,不再是特殊字符了
echo "The book store" | sed -n '/^book/p' # 行首不匹配,无输出
echo "Books are great" | sed -n '/^Book/p' # 行首匹配,输出匹配语句
echo "This ^ is a test" | sed -n '/s ^/p' # ^不再是特殊符号,由于脱字符出现在正则表达式模式的尾部,sed编辑器会将它当作普通字符来匹配
- 美元符(
$
)锁定在行尾
特殊字符美元符($)定义了行尾锚点。将这个特殊字符放在文本模式之后来指明数据行必须以该文本模式结尾。
echo "This is a good book" | sed -n '/book$/p' # 行尾匹配,输出匹配语句
echo "This book is good" | sed -n '/book$/p' # 行尾不匹配,无输出
- 组合锚点
可以在同一行中将行首锚点和行尾锚点组合在一起使用。
echo " this is a test " |sed -n '/^this is a test$/p'
echo " this is a test ? " |sed -n '/^this is a test$/p' # sed编辑器忽略了那些不单单包含指定的文本的行
将两个锚点直接组合在一起,之间不加任何文本,这样过滤出数据流中的空白行
2.1.2 点号字符(.
)
特殊字符点号用来匹配除换行符之外的任意单个字符。它必须匹配一个字符,如果在点号字
符的位置没有字符,那么模式就不成立
echo "This is a test of a line" | sed -n '/.at/p' # 无法匹配
echo "This test is at line four" | sed -n '/.at/p' # 在正则表达式中,空格也是字符,可以匹配
echo "at ten o'clock we'll go home" | sed -n '/.at/p' # 无法匹配
2.1.3 字符组
点号特殊字符在匹配某个字符位置上的任意字符时很有用。但如果你想要限定待匹配的具体字符呢?在正则表达式中,这称为字符组(character class)。
使用方括号来定义一个字符组。方括号中包含所有你希望出现在该字符组中的字符。然后你
可以在模式中使用整个组,就跟使用其他通配符一样
echo "Yes" | sed -n '/[Yy]es/p'
echo "This line has 1 number on it" | sed -n '/[0123]/p'
# 创建一个文本文件vim data.txt,内容如下
# 60633
# 46201
# 223001
# 22203
# 任意连续五位数字的字符都可以被匹配
sed -n '
>/[0123456789][0123456789][0123456789][0123456789][0123456789]/p
>' data8
# 如果指明行首^和行尾$,则只能匹配五位数字的字符
sed -n '
> /^[0123456789][0123456789][0123456789][0123456789][0123456789]$/p
> ' data8
2.1.4 排除型字符组
# 在字符组的开头加个脱字符(^)
echo "This test is at line four" | sed -n '/[^ch]at/p' data6
2.1.5 区间
# 以2.1.3文本文件data.txt为例
sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data.txt
# 同样的方法也适用于字母,可以匹配任意含有cat以及hat的文本
sed -n '/[c-h]at/p' data_name
# 该字符组允许区间a~c、h~m中的字母出现在at文本前,但不允许出现d~g的字母
sed -n '/[a-ch-m]at/p' data_name
2.1.6 特殊的字符组
组 | 描 述 |
---|---|
[[:alpha:]] | 匹配任意字母字符,不管是大写还是小写 |
[[:alnum:]] | 匹配任意字母数字字符09、AZ或a~z |
[[:blank:]] | 匹配空格或制表符 |
[[:digit:]] | 匹配0~9之间的数字 |
[[:lower:]] | 匹配小写字母字符a~z |
[[:print:]] | 匹配任意可打印字符 |
[[:punct:]] | 匹配标点符号 |
[[:space:]] | 匹配任意空白字符:空格、制表符、NL、FF、VT和CR |
[[:upper:]] | 匹配任意大写字母字符A~Z |
2.1.7 星号
在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次。
# 星号可以匹配任意次数
echo "ik" | sed -n '/ie*k/p'
2.2 扩展正则表达式
2.2.1 问号
问号类似于星号,不过有点细微的不同。问号表明前面的字符可以出现0次或1次,但只限于
此。它不会匹配多次出现的字符。
2.2.2 加号
加号是类似于星号的另一个模式符号,但跟问号也有不同。加号表明前面的字符可以出现1
次或多次,但必须至少出现1次
2.2.3 使用花括号
ERE中的花括号允许你为可重复的正则表达式指定一个上限。这通常称为间隔(interval)。可以用两种格式来指定区间。
m:正则表达式准确出现m次。
m, n:正则表达式至少出现m次,至多n次。
默认情况下,gawk程序不会识别正则表达式间隔。必须指定gawk程序的--re- interval
命令行选项才能识别正则表达式间隔
echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
2.2.4 管道符号(|)
管道符号允许你在检查数据流时,用逻辑OR方式指定正则表达式引擎要用的两个或多个模
式。如果任何一个模式匹配了数据流文本,文本就通过测试。如果没有模式匹配,则数据流文本
匹配失败。
echo "The cat is asleep" | gawk '/cat|dog/{print $0}' # 匹配
echo "The dog is asleep" | gawk '/cat|dog/{print $0}' # 匹配
echo "The sheep is asleep" | gawk '/cat|dog/{print $0}' # 不匹配
2.2.5 表达式分组
正则表达式模式也可以用圆括号进行分组。当你将正则表达式模式分组时,该组会被视为一
个标准字符。可以像对普通字符一样给该组使用特殊字符
echo "Sat" | gawk '/Sat(urday)?/{print $0}'
# Sat
echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
# Saturday
将分组和管道符号一起使用来创建可能的模式匹配组是很常见的做法
echo "cat" | gawk '/(c|b)a(b|t)/{print $0}'
# cat
echo "cab" | gawk '/(c|b)a(b|t)/{print $0}'
# cab
echo "bat" | gawk '/(c|b)a(b|t)/{print $0}'
# bat
网友评论