在本部落格中,”正規表達式”為一系列文章,如果你想要從頭學習怎樣在Linux中使用正則,可以參考此系列文章,直達連結如下:
“正則”系列的每篇文章都建立在前文的基礎之上,是以,請按照順序閱讀這些文章,否則有可能在閱讀中遇到障礙。
上一篇正規表達式的文章中,我們總結了跟”位置比對”有關的正則,此處,我們來認識一些跟”連續次數比對”有關的正則。
“連續次數比對”是什麼意思呢?空口白話說不容易明白,看完下例就能明白,首先,我們準備一個測試檔案,檔案内容如下。

測試文本regex.txt的内容如上圖所示。
如果我們想要從regex.txt文本中找出哪些行包含兩個連續的字母a,我們應該怎樣去查找呢?我們可以使用如下方法
沒錯,我們直接使用grep指令,在文本中搜尋”aa”即可,因為”aa”就是兩個連續的a字母。
可以看到,文本中的第二行和第三行中都包含兩個連續的a,是以第二行與第三行被列印了出來。
但是,如果我們要在文本中搜尋10個連續的a字母呢?好吧,我們可以搜尋”aaaaaaaaaa”字元串
如果我們想要在文本中搜尋100個連續的a字母呢?難道還要寫100個連續的a?這樣顯然有點累,我們可以利用正則解決這個問題,示例如下。
利用grep指令和正規表達式,即可找出哪些行包含2個連續的字母a ,示例如下
聰明如你一定看懂了,沒錯,”\{2\}”就表示”連續出現2次”,是以,”a\{2\}”就表示a連續出現兩次,可以看到,包含2個連續字母a的行隻有第二行,是以,當我們使用正規表達式”a\{2\}”時,隻能比對到第二行,由于第一行中的兩個字母a中間存在”空格”,是以并不能算作兩個連續的字母a,是以沒有被比對到。
你肯定已經學會舉一反三了,”\{2\}”表示連續出現2次,那麼,”\{5\}”就表示連續出現5次,”\{100\}”就表示連續出現100次,沒錯,我們隻要替換其中的數字,即可表示連續出現幾次。
我們總結一下剛才的文法
使用\{x\}表示之前的字元連續出現x次将會被比對到。
不過需要注意,如果字元連續出現的次數大于指定的次數,也是可以被比對到的,示例如下:
正規表達式中,我們指定,b字母連續出現2次則會被比對到,是以,第4行被比對到了,同時,第5行也被比對到了,因為第5行中,b字母連續出現了3次,包含2次,是以,前2個連續的字母b也被比對到了。
如果你不想出現上述情況,隻是想要精準的比對連續出現2次且隻出現了2次的字母b,應該怎麼辦呢?其實我們在前文中已經學到了解決問題的方法,示例如下
沒錯,就是結合了上次介紹到的單詞定界符,錨定詞首與錨定詞尾,如果你沒有看出來上述正規表達式什麼意思,那麼請回顧上一篇文章。
那麼現在,我們來
延伸一下,你來猜猜”\{x,y\}”表示什麼?
“\{x,y\}”表示之前的字元至少連續出現x次,最多連續出現y次,都能被比對到,換句話說,隻要之前的字元連續出現的次數在x與y之間,即可被比對到,示例如下。
如上圖所示,連續出現2次的d字母、連續出現3次的d字母、連續出現4次的d字母都被比對到了。
好了,現在我們已經了解了兩種文法。
\{x\} 表示之前的字元連續出現x次時會被比對到。
\{x,y\} 表示之前的字元至少連續出現x次,至多連續出現y次,都可以被比對到,x與y之間用逗号隔開。
那麼,我們再延伸一下,你猜猜… \{x,\} 與\{,y\} 分别表示什麼意思?
沒錯,你肯定已經猜到了
\{x,\}表示之前的字元至少連續出現x次,或者連續出現次數大于x次,即可被比對到,上不封頂。
\{,y\}表示之前的字元至多連續出現y次,或者連續出現次數小于y次,即可被比對到,最小次數為0次,換句話說,之前的字元連續出現0次到y次,都會被比對到。
示例如下:
如上圖所示,字母d連續出現2次以及2次以上的都被比對到了。
如上圖所示,abc、abcc都被比對到了,因為”c\{,2\}”表示隻要c字母連續出現的次數小于等于2,即可被比對到,再配合之前的”ab”字元,是以,abc
、abcc都被比對到了, ab為什麼也被比對到了呢?之前說過,”\{,y\}”表示之前的字元連續出現0次到y次,都會被比對到,是以,ab被比對到了,相當于c被比對到了0次。
現在我們再來認識一個用于比對次數的正則符号,它就是*
如果你之前使用過通配符,那麼你肯定對*非常熟悉,在通配符中,*表示比對任意長度的任意字元。
但是,在正規表達式中,*代表另一個意思,在正規表達式中,*表示之前的字元連續出現任意次數(包括0次),不要與通配符中的*搞混淆了。
示例如下
如上圖所示,”e*f”表示e出現任意次,f必須跟在e的後頭。
注意,*表示之前的字元連續出現任意次數,包括0次,即可被比對到,了解了這一點,再看如下示例,就簡單了。
如上圖所示,”d*”表示d連續出現任意次數,即可被比對到,是以,第7行高亮顯示了。
但是其他行為什麼也被列印出來了呢?這是因為*表示連續出現任意次數,包括0次。
其他行中,根本不包含字母d,換句話說就是,d連續出現了0次,是以其他行也符合條件,最終也被grep輸出了。
那麼,在通配符中,*表示比對任意長度的任意字元,在正則中,怎樣表示任意長度的任意字元呢?
在正規表達式中,使用”.*”表示任意長度的任意字元。
我們先看示例,回頭再解釋為什麼”.*”表示任意長度的任意字元,示例如下。
上圖中的正規表達式表示,a字母後面存在任意長度的任意字元,都可以被比對到,如上圖所示,的确都被比對到了。
其實,在正規表達式中,”.”表示比對任意單個字元,示例如下。
如上圖所示
“ee.”表示”ee”後面跟随任意一個單個字元,都會被比對到
“ee..”表示”ee”後面跟随任意兩個字元,都會被比對到,由于”空格”也算作單個字元,是以,”eef空格”也被比對到了,因為”f”和”空格”被看做了兩個字元。
了解完上述示例,再回過頭來了解”.*”,就容易多了,”.*”可以了解為”.”與”*”的結合,”.*”在正則中表示”連續出現任意次的任意單個字元”,換句話說就是,任意長度的任意字元,正規表達式中的”.*”與通配符中的”*”所表達的意思一樣。
了解完上述符号以後,再來認識兩個新符号,”\?”與”\+”
\?
表示比對其前面的字元0或1次,換句話說,就是前面的字元要麼沒有,要麼有一個。
\+表示比對其前面的字元至少1次,換句話說,就是前面的字元必須有至少一個。
我們來看看示例,如下。
如上圖所示,”c\?”表示c出現0次或者1次,都會被比對到,是以ab和abc都被比對到了,ab被比對到是因為c出現了0次,abc被比對到是因為c出現了1次。
看完上述示例後,再來看另外一個例子,如下:
可以看到,abc與abcc都被比對到了,這是因為”c\+”表示c至少要出現1次,至多可以連續出現多次,連續次數上不封頂,是以abc和abcc都會被比對到。
好了,關于”連續次數比對”的相關正規表達式就總結到這裡吧。
小結
為了友善以後回顧,我們将上述正則總結如下。
* 表示前面的字元連續出現任意次,包括0次。
. 表示任意單個字元。
.* 表示任意長度的任意字元,與通配符中的*的意思相同。
\? 表示比對其前面的字元0或1次
\+ 表示比對其前面的字元至少1次,或者連續多次,連續次數上不封頂。
\{n\} 表示前面的字元連續出現n次,将會被比對到。
\{x,y\} 表示之前的字元至少連續出現x次,最多連續出現y次,都能被比對到,換句話說,隻要之前的字元連續出現的次數在x與y之間,即可被比對到。
\{,n\} 表示之前的字元連續出現至多n次,最少0次,都會陪比對到。
\{n,\} 表示之前的字元連續出現至少n次,才會被比對到.
希望這篇文章能夠幫助到你,下次再見哦~~親~~~