本章内容:
- 定义正则表达式
- 正则表达式基础
- 扩展正则表达式
- 创建正则表达式
20.1 什么是正则表达式
20.1.1 定义
正则表达式是定义的模式模板(pattern template),Linux工具可以用它来过滤文本。
===
20.1.2 正则表达式的类型
两种正则表达式引擎
- POSIX基础正则表达式(BRE)引擎
- POSIX扩展正则表达式(ERE)引擎
sed只支持BRE引擎,出于速度方面的考虑。
20.2 定义BRE模式
20.2.1 纯文本
注意正则表达式区分大小写,在正则表达式中可以使用空格和数字。
$ echo "This is a test" | sed -n '/test/p'
This is a test
$ echo "This is a test" | sed -n '/trial/p'
$
20.2.2 特殊字符
正则表达式识别的特殊字符包括:
.*[]^${}+?|()
如果要使用特殊字符,必须在前面加上反斜线,做转义
$ cat data2
The cost is $4.00
$ sed -n '/\$/p' data2
The cost is $4.00
$ echo "\ is a special character" | sed -n '/\\/p'
\ is a special character
$ echo "3 / 2" | sed -n '/\//p' 3/2
===
20.2.3 锚字符
限制文本匹配发生的位置,如果不是在指定的位置出现,则不进行匹配
1.锁定在行首
无输出的情况:
$ echo "The book store" | sed -n '/^book/p'
$
$ echo "The book store" | sed -n '/^The/p'
The book store
2.锁定在行尾
$ echo "This is a good book" | sed -n '/book$/p'
This is a good book
$ echo "This book is good" | sed -n '/book$/p'
$
===
20.2.4 点号字符
点号字符可以用来匹配换行符之外的任意单个字符。
$ cat data6
This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.
at ten o'clock we'll go home.
$ sed -n '/.at/p' data6
The cat is sleeping.
That is a very nice hat.
This test is at line four.
第四行也会匹配,因为在正则表达式中,空格也是字符
===
20.2.5 字符组
$ sed -n '/[ch]at/p' data6
The cat is sleeping.
That is a very nice hat.
$ echo "yEs" | sed -n '/[Yy][Ee][Ss]/p'
yEs
===
20.2.6 排除型字符组
$ sed -n '/[^ch]at/p' data6 This test is at line four.
===
20.2.7 区间
$ echo "a8392" | sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p'
$
===
20.2.8 特殊的字符组
===
20.2.9 星号
在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次。
$ echo "ik" | sed -n '/ie*k/p'
ik
$ echo "iek" | sed -n '/ie*k/p'
iek
$ echo "ieek" | sed -n '/ie*k/p'
ieek
20.3 扩展正则表达式
ERE模式。gawk程序能够识别ERE。
20.3.1 问号
问号前面的字符可以出现0次或1次。
$ echo "bet" | gawk '/be?t/{print $0}'
bet
$ echo "beet" | gawk '/be?t/{print $0}'
$
===
20.3.2 加号
加号前的字符至少出现一次。
===
20.3.3 花括号
m: 正则表达式准确出现m次
m, n:正则表达式至少出现m次,至多n次
默认情况下 gawk不会识别正则表达式中的间隔,所以要加上 –re-interval
$ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
beet
$ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'
$
===
20.3.4 管道符号
逻辑or,只要满足其一即通过匹配
$ echo "The cat is asleep" | gawk '/cat|dog/{print $0}'
The cat is asleep
===
20.3.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
20.4 正则表达式实战
20.4.1 目录文件计数
先用空格替代冒号,将目录文件用空格分割,然后再利用for函数(以空格为间隔分辨元素)
$ cat countfiles
#!/bin/bash
# count number of files in your PATH
mypath=$(echo $PATH | sed 's/:/ /g')
count=0
for directory in $mypath
do
check=$(ls $directory)
for item in $check
do
count=$[ $count + 1 ]
done
echo "$directory - $count"
count=0
done
$ ./countfiles /usr/local/sbin - 0
/usr/local/bin - 2
/usr/sbin - 213
/usr/bin - 1427
/sbin - 186
/bin - 152
/usr/games - 5
/usr/local/games – 0
$
===
20.4.2 验证电话号码
^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}$
===
20.4.3 解析邮件地址
username可用字母,数字,字符,点号,单破折线,加号,下划线
^([a-zA-Z0-9_\-\.\+]+)@
顶级域名