深刻淺出正則表達式及grep,egrep異同解析

1、前言git

 在咱們初學Liunx時,就會遇到一攔路虎,那就是「正則表達式」。緣由在於其結構的複雜性和邏輯性較強,需大量的練習才能將其掌握。故本文主要整理總結了正則表達式在grep(和egrep)中的基本用法,使你們對正則表達式有個總體的認識。
正則表達式

2、名詞解釋bash

正則表達式:編輯器

    • 又稱正規表示法、常規表示法(Regular Expression,代碼中簡寫爲regex、regexp或RE);ide

    • 正則表達式使用單個字符串來描述、匹配一系列符合某個句法規則(即模式)的字符串;spa

    • 在不少文本編輯器裏,正則表達式一般被用來檢索、替換那些符合某個模式的文本;設計

    • 許多程序設計語言都支持利用正則表達式進行字符串操做,如Perl、Python等;regexp

元字符:ci

    • 正則表達式中具備特殊意義的專用字符(相似於C語言中的關鍵字);字符串

    • 不表示字符自己的意義,而是用於額外的功能性描述;

3、分類

    • 根據元字符數量和擴展功能,正則表達式通常分爲「基本正則表達式」和「擴展正則表達式」;

    • grep內置「基本正則表達式」的功能,也可以使用grep -E利用「擴展正則表達式」完成字符串匹配;

    • egrep內置「擴展正則表達式」的功能;

4、基本正則表達式(grep)

 基本正則表達式的元字符:

  1. 字符匹配

    .:任意單個字符
    [ ]:指定範圍內的任意單個字符
    [^]:指定範圍外的任意單個字符

    其中[ ]中字符範圍以下:

    [a-z]:匹配單個小寫字母
    [A-Z]:匹配單個大寫字母
    [0-9]:匹配單個數字
    [[:upper:]]:匹配單個大寫字母
    [[:lower:]]:匹配單個小寫字母
    [[:alpha:]]:匹配單個字母(不分大小寫)
    [[:digit:]]:匹配單個數字
    [[:alnum:]]:匹配單個字母或數字
    [[:space:]]:匹配單個空白(包括空格,tab等)
    [[:punct:]]:匹配單個標點符號
    [^]:指定範圍外的任意單個字符
  2. 次數匹配:用來指定匹配其前面字符的次數

    *:任意次(.*匹配任意長度的任意字符)
    \?:0次或1次
    \{m\}:匹配m次
    \{m,n\}:匹配m~n次
    \{m,\}:匹配至少m次
    \{0,n\}:匹配至多n次
  3. 位置錨定:用於指定字符出現的位置

    ^:錨定行首
    $:錨定行尾(^$表示空白行)
    \<:錨定詞首,也可表示爲\b
    \>:錨定詞尾,也可表示爲\b
  4. 分組:又可稱爲子模式

    \( \):如\(ab\)*xy
  5. 引用

    \1:後向引用,引用前面的第一個左括號以及與之對應的右括號中的模式所匹配到的內容

5、擴展正則表達式(egrep)

 「擴展正則表達式」較之「基本正則表達式」,元字符更加精簡,再也不須要反斜槓(\)轉義,且增長了+,|等元字符,以下:

  1. 字符匹配

    .:任意單個字符
    [ ]:指定範圍內的任意單個字符
    [^]:指定範圍外的任意單個字符
  2. 次數匹配

    *:匹配前面的字符任意次
    ?:匹配0或1次
    +:匹配至少1次(新增)
    {m}:匹配m次
    {m,n}:匹配m~n次
    {m,}:匹配至少m次
    {0,n}:匹配至多n次
  3. 位置錨定

    ^:行首
    $:行尾
    \<,\b:詞首
    \>,\b:詞尾
  4. 分組

    ( ):分組
    |:或 (新增)

  5. 引用:

    \1:後向引用,引用前面的第一個左括號以及與之對應的右括號中的模式所匹配到的內容

6、實例

Question1

顯示/etc/rc.d/rc.sysinit文件中以#開頭,後面跟至少一個空白字符,然後又有至少一個非空白字符的行

Answer1

grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit

Question2

顯示/boot/grub/grub.conf中以致少一個空白字符開頭的行

Answer2

grep "^[[:space:]]\{1,\}[^[:space:]]\{1,\}" /boot/grub/grub.conf

Question3

找出ifconfig命令結果中的1到255之間的整數

Answer3

ifconfig | egrep "\b([1-9][0-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])\b"

Question4

顯示/etc/passwd中用戶名和備註內容一致的行

Answer4

egrep "([[:alnum:]]+):.*:\1:" /etc/passwd

7、高級功能

非獲取匹配

    • 正則表達式中,能夠在子模式內部前面加「?:」來表示這個子模式只是一個「非獲取匹配」;

    • 「非獲取匹配」不會被保存,不能在後向引用中獲取;

    • 如(?:[[:digit:]]+) ([[:alpha:]]+) \1能夠匹配 555 abc abc,卻不能匹配 555 abc 555;

正向預查

    • 正則表達式中,能夠在子模式內部前面加「?=」來表示:首先,要匹配的文本必須知足子模式前面的表達式;其次,此子模式不參與匹配;

    • 相似於自定義的位於文本末的字符邊界\>;

    • 如 Windows (?=[[:digit:]]+\b)匹配結果是 Windows 95 和 Windows 98 中的Windows字段,後面的數字只是做爲匹配的依據而已;

反向預查

    • 與正向預查匹配方向相反,能夠在子模式內部前面加「?<=」來表示:首先,要匹配的文本必須知足子模式後面的表達式;其次,此子模式不參與匹配;

    • 相似於自定義的位於文本首的字符邊界\<;

    • 如 (?<=CNY: )[[:digit:]]+\.[[:digit:]]+ 能夠匹配CNY: 128.04CNY: 23.78 中數字字段,前面的CNY:字段只是做爲匹配的依據而已;

8、補充

fgrep:(fast grep)不解析正則表達式,只能對固定的字符串進行搜索,故速度較grep和egrep快

9、參考資料

《Regular Expression Cookbook》

相關文章
相關標籤/搜索