shell之正則表達式

        學習過編程語言的應該都聽說過正則表達式這個詞,那麼正則表達式到底是什麼呢?接下來就讓我們來了解一下。

       1、正則表達式簡介

         正則表達式是用於描述一組字符串特徵的模式,用來匹配特定的字符串。通過特殊字符+普通字符來進行模式描述,從而達到文本匹配目的。

        我們一般使用正則表達式是來進行模糊匹配。

        正則表達式的實驗場景有很多,一般我們在瀏覽網頁的時候

  • 驗證:表單提交的時候,對用戶名和密碼的驗證;
  • 查找:從海量的數據和信息裏面提取指定內容;例如在一批URL中查找指定的URL;
  • 替換:將指定格式的文本,進行正則匹配查找,找到之後進行特定替換;例如在vim編輯器裏進行文本替換的時候;

         2、正則表達式的三要素

        構建正則表達式有三個重要的指標,那就是正則表達式的三要素:字符類,數量限定符,位置限定符。當然有時還會有一些特殊符號。

        正則表達式與語言無關。

     3、grep工具的瞭解

     相信看到grep工具,我們應該不會很陌生,因爲在對文本內容進行查找或者過濾篩選的過程中我們經常會用到。那麼grep工具到底有什麼用處呢?

     (1)grep工具的簡介 

       grep (縮寫來自Globally search a Regular Expression and Print)是一種強大的文本搜索工具,它能使用特定模式匹配(包括正則表達式)搜索文本,並默認輸出匹配行。

        grep的工作方式是這樣的,它在一個或多個文件中搜索字符串模板。如果模板包括空格,則必須被引用,模板後的所有字符串被看作文件名。搜索的結果被送到屏幕,不影響原文件內容。

       grep可用於shell腳本,因爲grep通過返回一個狀態值來說明搜索的狀態,如果模板搜索成功,則返回0,如果搜索不成功,則返回1,如果搜索的文件不存在,則返回2。我們利用這些返回值就可進行一些自動化的文本處理工作。

     grep命令中允許指定的串語句是一個正則表達式,這是一種允許使用某些特殊鍵盤字符的指定字符串的方法,這種方法中的特殊鍵盤字符可以用於代表其他字符也可以進一步定義模式匹配工作方式。例如:grep ".*hood" essay1。該命令將在文件essay1中搜索,顯示出包含帶有字符串hood的字的每一行。命令行中的點表示的是hood之前可以有任意字符,星號指的是在字符串之前點號所表示的任意字符可以有任意個(其中的雙引號是可有可無的,但是當語句中包含短語或者空格時就必須加雙引號)。

     值得一提的是,grep工具在進行正則匹配的時候使用的是貪心匹配。grep工具在進行查找的時候是按照行來進行查找和過濾的。

   (2)grep命令   

           -E: 使用擴展正則匹配,後面介紹

           --color: 將匹配的到內容進行語法高亮

           -v:反檢索,只顯示不匹配的行。

           -i :忽略大小寫差別。

           -q:安靜模式匹配,取消顯示,只返回退出狀態。0則表示找到了匹配的行。

          -R:遞歸的讀取目錄下的所有文件,包括子目錄。 比如grep -R 'pattern' test會在 test 及其子目錄下的所有文件中,匹配 pattern。

          -V:顯示軟件版本信息。

          -o:只顯示與正則表達式匹配的部分。

          -n:顯示匹配的行,並且在匹配的行前面打印行號。

          -b:打印匹配行前面打印該行所在的塊號碼。
          -c:只打印匹配的行數,不顯示匹配的內容。
          -f:從文件中提取模板。空文件中包含0個模板,所以什麼都不匹配。
          -h:當搜索多個文件時,不顯示匹配文件名前綴。
          -l :打印匹配模板的文件清單。
          -L: 打印不匹配模板的文件清單。
          -s:不顯示關於不存在或者無法讀取文件的錯誤信息。

          -w:如果被\<和\>引用,就把表達式做爲一個單詞搜索。

     下面就使用grep工具來驗證一下正則表達式的三要素。

     字符類

字符含義
.匹配任意一個字符
[]匹配括號中的任意一個字符
-在括號內表示字符範圍
^位於[]括號的開頭,匹配除括號中的字符之外的任意一個字符
[[:xxx:]]grep工具預定義的一些命名字符類([[:alpha:]]匹配一個字母,[[:digit:]]匹配一個數字)

測試用例:

  

  

   數量限定符

字符含義
緊跟在它前面的單元應匹配零次或一次
+緊跟在它前面的單元應出現一次或多次
*緊跟在它前面的單元應匹配零次或多次
{N}緊跟在它前面的單元應精準匹配N次
{N,}緊跟在它前面的單元應匹配至少N次
{,M}緊跟在它前面的單元應匹配至多M次
{N,M}緊跟在它前面的單元應匹配至少N次,至多M次
測試用


位置限定符

字符含義
^匹配行首的位置
$匹配行末的位置
\<匹配單詞開頭的位置
\>匹配單詞結尾的位置
\b匹配單詞開頭或結尾的位置
\B匹配非單詞開頭或結尾的位置

測試用例:



特殊符號

字符含義
\轉義字符,普通字符轉義爲特殊字符,特殊字符轉義爲普通字符
()將正則表達式的一部分括起來組成一個單元,可以對整個單元使用數量限定符
|連接兩個子表達式,表示或的關係
測試用例:


        可以看出,()表示將其所包含的內容作爲一個整體,作爲一個單元,然後可以使用數量限定符來進行修飾限定。

         在我們使用grep工具進行測試的時候,一直都有一個-E選項,那這個選項到底有什麼用呢?去掉會有什麼不同呢?


   我們可以發現,在去掉-E選項之後,匹配結果出錯,並沒有按照我們的期望去正常匹配。這到底爲什麼呢?我們先來看兩個概念:

   基準正則表達式:Basic

   擴展正則表達式:Extended

區別:

      正則表達式的Extened規範和Basic規範基本相同,只是在Basic規範下,有些字符如 ?+ | {} ()應該被解釋爲普通的字符,要表示上述特殊字符必須要在前面加上\進行轉義。在Extended規範下,?+| {}()應該被解釋爲特殊字符,要取其字面值,也必須對其進行轉義。

      所以grep工具帶上-E選項,表示使用擴展正則來進行匹配,若沒有,則表示使用基準正則來匹配。上述問題就可以如下解決:


      那麼,如果在目標字符串中本來就包含了這些字符,想要匹配的話,我們應該怎麼做呢?當然,這下就需要用到剛剛說的\轉義了。


其他常用通用字符集及其替換

符號替換正則匹配
\d[0-9]數字字符
\D[^0-9]非數字字符
\w[a-zA-Z0-9_]數字字母下劃線
\W[^\w]非數字字母下劃線
\s[_\r\t\n\f]表格,換行等空白區域
\S[^\s]非空白區域

測試用例:


在上述測試用例中,-E選項進行\d匹配的出錯,這是爲什麼呢?因爲正則表達式分爲三類:

   基準的正則表達式:Basic(BREs)

   擴展的正則表達式:Extended (EREs)

   Perl的正則表達式: (PREs)

grep , egrep 正則表達式特點:

   grep 支持:BREs、EREs、PREs 正則表達式

   grep 指令後不跟任何參數,則表示要使用 ”BREs“

   grep 指令後跟 ”-E" 參數,則表示要使用 “EREs“

   grep 指令後跟 “-P" 參數,則表示要使用 “PREs"

所以,要解決上述問題,必須使用-P 選項

    在瞭解了什麼是正則表達式以及簡單實用了正則表達式後,接下來做兩個小練習。

  首先創建一個文件file


(1)在一個文件中查找電話號碼


(2)在一個文件中查找日期


(3)在匹配IP地址


    3、零寬斷言

    斷言用來聲明一個應該爲真的事實。正則表達式中只有當斷言爲真時纔會繼續進行匹配。 接下來的四個用於查找在某些內容(但並不包括這些內容)之前或之後的東西,也就是說它們像\b,^,$ 那樣用於指定一個位置,這個位置應該滿足一定的條件(即斷言),因此它們也被稱爲零寬斷言。

  零寬斷言: 不匹配長度,只是爲了用正則表達式來確定一個位置。

(1)(?=exp)也叫零寬度正預測先行斷言: 它斷言自身出現的位置的後面能匹配表達式exp。

(2)(?<=exp)也叫零寬度正回顧後發斷言:它斷言自身出現的位置的前面能匹配表達式exp。


  好了,以上就是我所總結的關於shell的正則表達式的相關概念及測試用例。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章