背景
一直對Regex瞭解不多,今天又碰到一個奇怪的問題,看如下例子
[root@devserver ~]# echo application |grep k*napplication
想了半天也沒明白,在application裡面沒有字母k,會能匹配呢。發現無論把k替換成任何字母都是會匹配成功的。
隨即從百度百科看了仔細用法:
| * |
匹配前面的子運算式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等價於{0,}。 |
對例子中的zo*能匹配z仔細體會,終於明白了*號前面的字母任意次。因此在之前的例子中是對的。
深入瞭解看下面的執行結果
[root@devserver ~]# echo application | grep a*napplication[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.*napplication[root@devserver ~]# echo application | grep a[a-z]*napplication[root@devserver ~]# echo application | grep a[a-z1-9]*napplication
使用:lower:替換.*,也都是可以的
[root@omsdevserver ~]# echo application | grep app[[:lower:]]*napplication[root@omsdevserver ~]# echo application | grep app[[:upper:]]*n[root@omsdevserver ~]# echo application | grep app[[:upper:][:lower:]]*napplication
為什麼我們會覺得奇怪日常工作中,用Regex是比較少的。但是用shell是比較多的,比如尋找檔案
[root@omsdevserver ~]# ls in*loginstall.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
在這種情況下,並不是使用Regex的規則來進行的,而只是一種PATTERN.