通過grep學習正規表示式

2021-08-21 09:31:32 字數 4006 閱讀 1268

在linux的學習當中,正規表示式是非常重要的部分,現在我想通過grep命令來解析和學習正規表示式,同時也能將grep的相關功能展示清楚。

從乙個例子開始

上述例子我試圖從test.txt中獲取字串a line所在的行。

那麼這個過程中到底發生了什麼呢?我們從下面的示意圖中可以有所了解

從上圖可以很直觀的看出,grep在處理模式匹配的時候,將檔案的每一行作為乙個單獨的字串,然後和我們設定好的模式逐一進行比對,如果找到了想要的模式,就返回對應的行,如果沒找到就丟棄到該行。此外,我們可以看出來空格在模式匹配的時候也是佔乙個字元的這就是為什麼aline沒有出現在結果中。

事實上,正規表示式就是模式匹配的一種規則,有時候我們想要匹配的內容並不是完全一樣的,而是具有一定共同規律的字串,例如love,lover,lovers都有共同的部分love,如果我們要匹配這三種不同的字串可以直接使用love進行匹配,但是如果我們只想要love,那麼就不能僅僅用love來進行限定了,還需要新增一些其他的限制。而正規表示式就能為我們提供一種方便快捷的符號表示方式,來讓我們實現更加複雜的一些匹配過程。很多不同的程式設計語都支援正規表示式,例如r,python,perl,shell等,在shell中,grep,awk,sed都支援正則匹配,不過正則匹配本身有基礎和擴充套件的部分,現在我們來逐一認識一下它們吧。

bre(basic regular expression)

^錨定符,錨定字串開始

$錨定符,錨定字串結束

.d代表除\n以外的任意符號

*前乙個位置的字元出現0次或多次

方括號表示式,該方括號佔乙個字元的位置,包含該位置可能出現的字元[^]代表取反

這五個特殊符號是最常用到的正規表示式符號,看乙個例子

分別提取包含bam的行和以bam結尾的行

我們可以通過錨定符來確定我們要的字串的位置。grep新增--color引數可以高亮匹配到的字串。

ere(extended regular expression)

x匹配前面位置的字元模式最少n次,最多m次

|交替,指定該位置可以出現豎槓前模式或者豎槓後模式,例如:a|b代表該位置可以是a或者b

?前面指定的字元模式出現0次或者1次,例如a?代表a可以出現0次或者1次

+指定前面的字元模式可以出現一次或者多次,但不能不出現

()括號內的內容被當作乙個整體進行匹配,可以結合其他字元進行,例如(abc)|(bcd)代表該位置可以是abc或者bcd

;(abc)代表abc模式出現至少2次,至多3次

擴充套件正則擴充了正則的功能,我們可以指定匹配模式的個數以及進行分組,()分組是非常重要的乙個功能,分組功能可以提公升其他正則符號的使用防範和方法,並且衍生出了向後引用的用法。接下來我們從例子中了解一下分組功能帶來的改變

在grep中使用擴充套件正則需要新增-e引數,我們分別使用如下兩種方式來進行匹配,並且高亮匹配到的部分,看看有什麼不同

雖然搜尋的結果是一樣的,但是我們發現兩次匹配到的字串部分並不相同,通過()分組符號,我們可以使得其他正則符號的

作用域發生改變,在這個例子中,()使得|符號的作用域從.*\txt變成了txt,進而實現了|符號只對檔名的字尾起作用。分組是正則中很重要的組成部分,它使得我們可以將正規表示式分成多個部分,然後逐個去解決。

接下來展示乙個向後引用的例子

下面的例子我們試圖尋找到like liker 這樣的模式,也就是重用我們之前匹配的部分,為此我們需要先對需要重用的部分增加分組,然後使用\num的方式進行引用,由於這是第乙個分組,因此就可以使用\1來引用

cat test5.txt

like liker

love lover

like lover

love liker

grep -e '([a-z]+) \1r' test5.txt

like liker

love lover

最後,我們通過挑選正確郵箱的例子來展示正規表示式的使用

我們要從一些郵箱中挑選出滿足以下條件的郵箱

@和最後乙個點(.)之間必須有內容且只能是字母(大小寫)、數字、點(.)、減號(-),且兩個點不能挨著

最後乙個點(.)之後必須有內容且內容只能是字母(大小寫)、數字且長度為大於等於2個位元組,小於等於6個位元組

可以看下126郵箱註冊的介面

這裡也可以把紅框中的條件加上。

那麼這個正則應該怎麼來寫呢?先看下乙個郵箱例子的集合,其中有正確,也有錯誤郵箱,我們要做的就是提取正確的郵箱

cat test4.txt
[email protected]

[email protected]

[email protected]

888888@,qq.com

abcde_@qq,com

[email protected]

[email protected]

88888@

[email protected]

grep -p '^[a-za-z][\w-.]@[\w-]+(\.[\w-]+)*\.[a-za-z0-9]$' test4.txt
[email protected]

[email protected]

abcde_@qq,com

這裡我們使用了grep -p 引數,-p引數指使用perl的正規表示式,在該模式下,我們可以使用\w來代表數字字母下劃線,我們藉此簡化我們的操作。

該正則中值得關注的點是,對於可能出現的部分,我們使用()進行分組並新增*來表示其可能出現也可能不出現的情況,需要注意的是,當我們在正規表示式中想要匹配 ' . '的時候,需要加反斜槓進行轉義。

這個正規表示式不嚴格的地方在於無法過濾掉***x@_.com的郵箱位址,這裡我們可以稍作修改,如下

grep -p '^[a-za-z][\w-.]@[a-za-z0-9][\w-]*(\.[\w-]+)*\.[a-za-z0-9]$' test4.txt
最後讓我們回顧一下本次部落格所設計的關鍵內容:

grep正規表示式

grep的工作方式是這樣的,它在乙個或多個檔案中搜尋字串模板。如果模板包括空格,則必須被引用,模板後的所有字串被看作檔名。搜尋的結果被送到螢幕,不影響原檔案內容。grep可用於shell指令碼,因為grep通過返回乙個狀態值來說明搜尋的狀態,如果模板搜尋成功,則返回0,如果搜尋不成功,則返回1,如果...

Grep正規表示式

grep正規表示式 要用好grep這個工具,其實就是要寫好正規表示式,所以這裡不對grep的所有功能進行例項講解,只列幾個例子,講解乙個正規表示式的寫法。ls l grep a 通過管道過濾ls l輸出的內容,只顯示以a開頭的行。grep test d 顯示所有以d開頭的檔案中包含test的行。gr...

grep正規表示式

文字查詢需要grep global research 根據模式,搜尋文字,並將符合模式的文字行顯示出來。pattern 文字字元和正規表示式的元字元組合而成的匹配條件 man grep 檢視幫助 查詢 etc passwd檔案包含root的內容 root iz233y80y23z grep root...