背景
一直对正则表达式了解不多,今天又碰到一个奇怪的问题,看如下例子
[root@devserver ~]# echo application |grep k*n
application
想了半天也没明白,在application里面没有字母k,会能匹配呢。发现无论把k替换成任何字母都是会匹配成功的。
随即从百度百科看了仔细用法:
*
|
匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。
|
对例子中的zo*能匹配z仔细体会,终于明白了*号前面的字母任意次。因此在之前的例子中是对的。
深入了解
看下面的执行结果
[root@devserver ~]# echo application | grep a*n application [root@devserver ~]# echo application | grep ap*n //只能匹配 an apn appn appppn [root@devserver ~]# echo application | grep ap.*n //这里.表示任意字符,因此.*是可以表示中间的任意字符 application [root@devserver ~]# echo application | grep app.*n //同上 application
继续看下去,使用[a-z]替换.*
[root@devserver ~]# echo application | grep a.*n application [root@devserver ~]# echo application | grep a[a-z]*n application [root@devserver ~]# echo application | grep a[a-z1-9]*n application使用:lower:替换.*,也都是可以的
[root@omsdevserver ~]# echo application | grep app[[:lower:]]*n application [root@omsdevserver ~]# echo application | grep app[[:upper:]]*n [root@omsdevserver ~]# echo application | grep app[[:upper:][:lower:]]*n application
为什么我们会觉得奇怪
日常工作中,用正则表达式是比较少的。但是用shell是比较多的,比如查找文件
[root@omsdevserver ~]# ls in*log install.log install.log.syslog但是我们从来不会用查找install.log文件
[root@omsdevserver ~]# ls ik*log
因此,我们主观认为grep ik*log是不能匹配的
通过查找资料发现,shell中*是指expansion。我们上面用的是最常用的Filename expansion。
After word splitting, unless the -f option has been set (see Section 2.3.2), Bash scans each word for the characters "*", "?", and "[". If one of these characters appears, then the word is regarded as a PATTERN, and replaced with an alphabetically sorted list of file names matching the pattern
在这种情况下,并不是使用正则表达式的规则来进行的,而只是一种PATTERN.