SECTION 24 正则表达式

1. 正则表达式

正则表达式是你所定义的模式模板(pattern template),linux工具用它来过滤文本
正则表达式通过正则表达式引擎(regular expression engine)实现,正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配

在linux中,有两种主流的正则表达式引擎:

POSIX基础正则表达式(basic regular expression,BRE)引擎
POSIX扩展正则表达式(extended regular expression,ERE)引擎

大多数linux工具至少符合BRE引擎规范,能够识别该规范定义的所有模式符号

2. BRE模式

纯文本:正则表达式区分大小写
正则表达式识别特殊字符包括:.*[]^${}\+?|()
如果要用某个特殊字符作为文本字符,就必须通过转义符(\)进行转义

]# sed -n '/\$/p' data.txt 

尽管/不是特殊字符,但是如果匹配该字符仍需转义

]# echo 'safsa/fsadf' |sed -n '/\//p'
safsa/fsadf
]# echo 'safsa/fsadf' |sed -n '///p'
sed: -e expression #1, char 3: unknown command: `/'
  • 锚字符

2.1 锁定在行首

脱字符(^)定义从数据流文本行中的行首开始的模式,格式:
^pattern
必须放在模式前,如果放在模式中的其他位置,将会视为普通字符

]# sed -n '/^Ad/p' data.txt 
Adadsadfsad;df*$

2.2 锁定在行尾

美元符($)定义了行尾锚点,格式
pattern$
必须放在模式后,同样放在模式中的其他位置,视为普通字符

]# sed -n '/9$$/p' data.txt 
2629$

2.3 组合锚点

^和$组合

]# sed -n '/^262$$/p' data.txt 
262$
]# sed -n '/^$/p' data.txt 

匹配空行,删除空行

]# sed  '/^$/d' data.txt 
ASDLKFJASDKF
Adadsadfsad;df*$
2629$
262$
eecho12312412
_sfsadf222312#@
[root@localhost day8]# cat data.txt 
ASDLKFJASDKF
Adadsadfsad;df*$
2629$

262$
eecho12312412
_sfsadf222312#@

2.4 点号字符

特殊字符点号(.)用来匹配除了换行符之外的任意单个字符,它必须匹配一个字符,如果在点号字符位置没有字符,则模式不匹配

]# sed -n '/2.29/p' data.txt 
2629$
]# echo 'at this time'|sed -n '/.at/p'
]# echo 'hat this time'|sed -n '/.at/p'
hat this time

2.5 字符组

如果要限定待匹配的具体字符,称为字符组(character class)
如果字符组中的某个字符出现在了数据流中,它就匹配了模式
使用[]来定义一个字符组,方括号中包含所有你希出现在该字符组中的字符

]# sed -n '/[4*#]/p' data.txt 
Adadsadfsad;df*$
eecho12312412
_sfsadf222312#@

2.6 排除型字符组

在字符组开头加脱字符,起到反转字符组作用,正则表达式会匹配不包含在排除型字符组的字符,格式
[^xxx]

]# cat data.txt 
This is a test of a line #不包含at,所以不匹配
the bcat is sleeping 
That is a very nice hat
This test is at line four #空格也算字符,所以批评
at ten o'clock we'll go home #at前无字符,至少应有一个字符
]# sed -n '/[^ch]at/p' data.txt 
This test is at line four

注意:即使是排除,字符组仍然必须匹配一个字符,空格也是字符

]# sed -n '/[^ch]at/p' data.txt 
cat ,This test is at line four

特别注意:如果单行内容中,前部分匹配排除字符组,而后面有不匹配排除字符组,但能匹配模式的内容,仍能匹配,并非包含排除匹配后面不进行匹配

2.7 区间

根据linux采用的字符集,区间包括
数字区间[0-9]
字母区间[a-z][A-Z]
也可以指定区间[c-h],只能是上述区间子集

]# sed -n '/[a-d]at/p' data.txt 
the bcat is sleeping
cat ,This test is at line four

2.8 特殊字符组

BRE特殊字符组:

描述
[[:alpha:]]匹配任意字母字符,不管大小写,[a-z],[A-Z]
[[:alnum:]]匹配任意字母字符和数字,[0-9],[a-z],[A-Z]
[[:blank:]]匹配空格或值表符
[[:digit:]]匹配数字,[0-9]
[[:lower:]]匹配小写字母,[a-z]
[[:print:]]匹配任意可打印字符
[[:punct:]]匹配标点符号
[[:space:]]匹配任意空白字符,空格,制表,NL,FF,VT,CR
[[:upper:]]匹配大写字母,[A-Z]
]# echo "hello,world"|sed -n '/[[:punct:]]/p'
hello,world
]# echo "hello world"|sed -n '/[[:punct:]]/p'
]# echo "hello world"|sed -n '/[[:space:]]/p'
hello world

2.9 星号

在字符后面放置星号(*),表明该字符必须在匹配模式的文本中出现0次或多次

]# echo "hello world"|sed -n '/wor*ld/p'
hello world
]# echo "hello worrld"|sed -n '/wor*ld/p'
hello worrld

点星组合
能够匹配任意数量的任意字符

]# echo "hello worrr  sdaf ld"|sed -n '/w.*ld/p'
hello worrr  sdaf ld

只要包含w在前,ld在后的字符串都匹配

星号和字符组组合
允许指定可能在文本中不出现或出现多次的字符组或字符区间
但是只能字符区间内的字符,次数不限,出现其他字符则不匹配

]# echo 'bat' | sed -n '/b[ae]*t/p'
bat
]# echo 'bakt' | sed -n '/b[ae]*t/p'
]# echo 'baeeeeet' | sed -n '/b[ae]*t/p'
baeeeeet

3. ERE模式

gawk能识别ERE模式,sed不支持,所以单从处理数度来说,gawk要慢些

3.1 问号(?

问号表明前面字符可以出现0次或1次,不会匹配多次

]# echo 'bt'|gawk '/be?t/{print $0}'
bt
]# echo 'bet'|gawk '/be?t/{print $0}'
bet
]# echo 'beet'|gawk '/be?t/{print $0}'

3.2 加号(+)

加号表明前面字符可以出现1次或多次至少出现1次

]# echo 'beet'|gawk '/be+t/{print $0}'
beet

3.3 花括号({})

ERE中花括号允许你为可重复的正则表达式指定一个上限,通常称为间隔(interval),可以使用两种格式指定区间

  • {m}: 正则表达式准确出现m次
  • {m,n}: 正则表达式至少出现m次,至多n次

gawk中必须指定–re-interval命令行选项才能识别间隔,默认无法识别

]# echo 'beet'|gawk '/be{2}t/{print $0}'
beet
[root@localhost day8]# echo 'beet'|gawk '/be{1,2}t/{print $0}'
beet
]# echo 'beet'|gawk '/be{2,3}t/{print $0}'
beet
]# echo 'beet'|gawk '/be{1}t/{print $0}'
]# echo 'beet'|gawk '/be{3,5}t/{print $0}'

注意:间隔为闭区间,两侧上下限均包含
区间仍适用

]# echo 'beet'|gawk '/b[ea]{2,3}t/{print $0}'
beet
]# echo 'beat'|gawk '/b[ea]{2,3}t/{print $0}'
beat
]# echo 'beaeat'|gawk '/b[ea]{2,3}t/{print $0}'

3.4 管道符号(|)

管道符号允许你再检查数据流时,用逻辑OR方式指定正则表达式引擎要用的两个或多个模式,如果任何一个模式匹配,文本通过,格式
expr1|expr2|...

]# echo 'this cat sheep pig'|gawk '/cat|dog/{print $0}'
this cat sheep pig
]# echo 'this sheep pig'|gawk '/cat|dog/{print $0}'

3.5 分组表达式

正则表达式也可以用圆括号(())进行分组,当使用分组时,该组会被视为一个标准字符

]# echo 'this cat sheep pig'|gawk '/(ep)?/{print $0}'
this cat sheep pig
]# echo 'this cat sheep pig'|gawk '/(t s)?/{print $0}'
this cat sheep pig
]# echo 'this cat sheep pig'|gawk '/(t p)+/{print $0}'

组合

]# echo 'this cat sheep pig'|gawk '/(c|d)a(t|f)/{print $0}'
this cat sheep pig
]# echo 'this cat sheep pig'|gawk '/(c|d)a(e|f)/{print $0}'

4. 实例

  • 统计PATH中定义的目录中可执行文件的数量
#!/bin/bash

mypath=$(echo $PATH|sed 's/:/ /g') 	#通过空格替换分隔符:,分隔PATH
#echo $mypath

count=0

for item in $mypath;do			#迭代分隔后的PATH
        diretory=$( ls $item)		#列出每个目录中的可执行文件
        for i in $diretory;do
                count=$[ $count+1 ]	#统计数量
done
        echo "$item - $count"
        count=0
done
  • 验证电话号码
    电话簿
]# cat phone 
(123)456-7890
(123) 456-7890
223-345-7890
123.456.7890

电话简单要求:

1.以(或者数字开头
2.第一个数字必须时2-9,二三位必须是数字0-9
3.第四位必须是空格,-或者点
4.接着3位数字
5.接着必须是空格,-或者点
6.接着4位数字

]# cat iphone.sh 
#!/bin/bash

gawk --re-interval '/^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}$/{print $0}'
]# cat phone |./iphone.sh 
223-345-7890
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值