bash,  Research & Study

bash – 基本文法教學 #3

正規表示法

正規表示式 ( Regular expressions , 簡稱 regex ) 是一種用來比對文字的方法,相當便利。

在 bash 中,只有複合式指令才會使用到正規表示式,但是還是痕值得學習,因為正規表示式會牽扯到很多工具,像是 grep、awk 和 sed 等等。

範例文件 - frost.txt

1     Two roads diverged in a yellow wood,
2     And sorry I could not travel both
3     And be one traveler,long I stood
4     And looked down one as far as I could
5     To Where it bent in the undergrowth;
6
7 Excerpt from The Road Not Taken by Robert Frosr

正規表示式 - grep

為方便展示,下方使用grep進行正規表示式的講解。grep 指令通常用於檔案內容的搜尋。透過指定樣式,可以比對使否有符合條件的內容。

用法

grep options pattern filenames

         (選項)    (參數)      (檔名)

常用指令

  • – c : 計算符合比對樣式的行數。
  • -E : 啟用更廣義的正規表示式。
  • -f : 從指定檔案讀取要搜尋的樣式。檔案中可以包含多種樣式。一行表示一種樣式。
  • -i : 忽略字元大小寫。
  • -l : 只印出符合比對樣式的檔案名稱和路徑。
  • -n : 印出檔案中符合比對樣式的行號。
  • -P : 啟用 Perl 的正規表示式引擎。
  • -R,r : 遞迴搜尋子目綠。

舉例

若需要在家目錄和其子目錄搜尋含有 security 字樣的檔案,指令如下所示 :

 

grep -R -i ‘security’  /home

 

正規表示式的中介字符

“正規表示式” 其實就是中介字符和很多字元所組合的樣式。

在正規表示式中,有很多特殊符號有特殊意義。

中介字符

句號 ( . )

  • 代表單一萬用字元
  • 可以比對出任何單一字元,換行字元例外

$  grep ‘T.o’ frost.txt

1     Two roads diverged in a yellow wood,

問號 ( ? )

  • 問號會讓它前面的任何項目都變得可有可無
  • 允許出現一個、或是沒有項目

$ egrep ‘T.?o’ frost.txt

1     Two roads diverged in a yellow wood,

5     To Where it bent in the undergrowth;

星號 ( * )

  • 比對出出現過1次以上、或是根本未出現
  • 與 ? 很像,差別在於允許次數一次以上

$ grep ‘T.*o’ frost.txt

1     Two roads diverged in a yellow wood,

5     To Where it bent in the undergrowth;

7 Excerpt from The Road Not Taken by Robert Frosr

加號 ( + )

  • 與星號一樣,但必須要求一次以上
  • 會比對出出現至少一次的前置樣式

$ egrep ‘T.+o’ frost.txt

1     Two roads diverged in a yellow wood,

5     To Where it bent in the undergrowth;

7 Excerpt from The Road Not Taken by Robert Frosr

群聚

  • 透過小括弧來集合字元
  • 允許將出現在誇胡中的字元視為事後可以比對參照的單一項目

$ egrep ‘And be one (stranger|traveler), long I stood’ frost.txt

3     And be one traveler,long I stood

中括號和字元種類

中括號通常用來定義字元種類,詳細如下所示 :

  • [abc] : 只比對出a、b、c
  • [1-5] : 只比對出1~5的數字
  • [a-zA-Z] : 只比對出大寫或小寫的英文字母
  • [0-9±*/] : 只比對出數字或是四則運算
  • [0-9a-fA-F] : 只比對出16進位數字

捷徑

有一系列預先定義好的字元種類,稱之為捷徑

  • \s : 空白
  • \S : 非空白
  • \d : 數字
  • \D : 非數字
  • \w : 字詞
  • \W : 非字詞
  • \x : 十六進位數字(例如0x5F
      • 需要注意注意, egrep 不支援捷徑
      • 需要利用grep -P

一系列字元種類

如果需要對初連續多個字元,可以利用*或是+來製作出需要的效果。

  • [:alnum:] – 數字和字母字元
  • [:alpha:] – 純字母字元
  • [:cntrl:] – 控制字元
  • [:digit:] – 數字字元
  • [:graph:] – 任何控制和空白字元以外的字元
  • [:lower:] – 小寫字母
  • [:print:] – 任何控制字元以外的字元
  • [:punct:] – 標點符號字元
  • [:space:] – 包括換行符號在內的空白字元
  • [:upper:] – 大寫字母
  • [:xdigit:] - 任何十六進位字元

回朔參照

很好用,但相對比較複雜,需要花一點時間去整理。

範例檔案 tag.txt 如下 :

 

 1    Command
2     <i>line</i>
3     is
4     <div>great</div>
5     <u>!</u>

像這種 html 會被被 HTML標籤包起來的問題,如果需要至找到標籤語言,可以透過回朔功能

  • \1 的部分,會回去參考第一個表示式(第一個小括號裡面的)
  • \1 代表第一組小括號,\2代表第二組,以此類推

$ egrep ‘<([A-Za-z]*)>.*</\1> tags.txt

<i>line</i>
<div>great</div>
<u>!</u>

定位符號 & 字詞邊界

  • 溢出字元(^)就是將樣式鎖在字串開頭
    • ^[1-5]代表需要式1到5開頭才算符合
  • $字元則是將樣式鎖在結尾
    • [1-5]$則是必須1到5做結尾才算符合
  • \b 則是用來界定字詞邊界(例如空白)
    • \b[1-5]\b 則代表會比對出任何介於空間之間的1到5的數字

相關資源

  • http://www.rexegg.com/
  • https://regex101.com/
  • https://www.regextester.com/
  • https://www.regular-expressions.info/

留下一個回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *