正則表達式筆記

關於正則表達式

正則表達式可以通過元字符(規則)來匹配查找相關的的字符集合。他與通配符是有區別的。而且相關的使用工具對正則表示的元字符的是有區別的。

    首先我們先來了解下常用的元字符及含義(並不是所有的元字符),主要以bash中的grep爲使用機制。


字符匹配 

        .(點)一個任意字符,回車符換行符除外        

        [ ]匹配所包含的任意一個字符

                [^xyz]負值字符集合。匹配未包含的任意字符。

        [a-z]字符範圍。匹配指定範圍內的任意字符。

        注意:只有連字符在字符組內部時,並且出現在兩個字符之間時,才能表示字符的範圍;

        如果出字符組的開頭,則只能表示連字符本身.

        [^a-z]^表示取反;匹配不在指定範圍內的任意一個字符。

        [:space:] 一個空白字符

        [:punct:] 一個(所有)標點符號

        [:lower:] 一個小寫字母 [a-z]  不能寫成[z-a]

        [:upper:] 一個大寫字母 [A-Z]

        [:digit:]  一個數字     [0-9]

        [:alnum:] 一個數字和字母 [A-Z0-9a-z]

        [:alpha:]  一個大小寫字母 [a-zA-Z]

位置錨定

        ^ 匹配輸入字符串的開始位置。行首  寫在左側

        $匹配輸入字符串的結束位置。寫在行尾

        \b匹配一個單詞邊界,

        \B匹配非單詞邊界。

        \< \>匹配詞(word)的開始(\<)和結束(\>)。

重疊次數

        *匹配前面的子表達式、字符零次或多次(大於等於0次)。

        +匹配前面的子表達式一次或多次(大於等於1次)

        ?匹配前面的子表達式零次或一次。(基本表達式需要轉意 \)

        {n}前面字符匹配n次。 (基本表達式需要轉意 \)

        {n,}至少匹配n次,至多不管啊   (基本表達式需要轉意 \)

        {n,m}其中n<=m。最少匹配n次且最多匹配m次。  (基本表達式需要轉意 \ )

特殊功能

        ( ) 將 \( 和 \) 之間的表達式定義爲“組”(group),並且將匹配這個表達式的字符保存到

        一個臨時區域

        (一個正則表達式中最多可以保存9個),它們可以用 \1 到\9 的符號來引用。分組中的模式

         匹配到的內容,

        可由正則表達式引擎記憶在內存中,之後可被引用有編號:自左而後的左括號,以及與其匹配

        右括號

        (基本表達式需要轉意 \)

        \n引用第n個括號所匹配到的內容,而非模式本身

        |將兩個匹配條件進行邏輯“或”(Or)運算。擴展正則表達式

        \轉義符號,把後面的字符特殊的轉爲普通,普通的轉爲特殊

    這上面的這些字符沒有別的辦法就是記住和理解,其實就是規則文字遊戲並不是一開始接觸時候的時候所認認爲的那麼難。重要的是先對單個元字符去實驗下然後再去組合。綜合而言正則表達式就是計算機所能識別的並被人類所能操作的一種語言,他有很多組合方式來實現你所想要的功能。

    使用正則表達式之前首先肯定是有需求或者說是目標,然後分析組合匹配規則。在這裏我感覺還是使用擴展正則表達式的好,無需糾結。

    

首先準備一串字符,我放在了/tmp/ceshi

    130 120 200 450 12 24 70 140 8000 30

    30 120 200 450 12 24 170 140 80

    78 30 1800 200 450 12 24 170 40 80

    30 1800 200 450 120 24 170 40 70 70 70

    389 30 1800 200 450 120 24 1000 40 70

    30 30 1800 200 450 120 24 1000 40 70

    130120 200 450122470140800030

    30120200450122417014080

    7830180020045012241704080

    3018002004501202417040707070

    3893018002004501202410004070

    303018002004501202410004070

    

匹配下以30開頭中間必須含有70的字符串:

    1、單個匹配以30爲開頭:需要做行首錨定^30

    2、單個含有70: 70 

    3、組合匹配需要注意中間30和70之間是可以經過任意字符的.*

    ^30.*70

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "^30.*70"

    30 120 200 450 12 24 170 140 80

    30 1800 200 450 120 24 170 40 70 70 70

    30 30 1800 200 450 120 24 1000 40 70

    30120200450122417014080

    3018002004501202417040707070

    303018002004501202410004070

    

 再來匹配下以30開頭中間必須包含1800以70結尾的字符串:

    還是同樣的步驟分析幾個重要的點

    1、30開頭:^30

    2、中間必須包含1800: 1800前後都有可能存在字符 .*1800.*

    3、以70結尾:70$

    ^30.*1800.*70$

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "^30.*1800.*70$"

    30 1800 200 450 120 24 170 40 70 70 70

    30 30 1800 200 450 120 24 1000 40 70

    3018002004501202417040707070

    303018002004501202410004070

    要求30後面需要跟一個空白字符呢?

    要求30後面需要跟上1或者3呢?   

    ^30[ ].*1800.*70$

    ^30[1|3].*1800.*70$

再來試幾個簡單的實例


 1、要求70 至少出現2次最多出現3次

    我們需要用到{n,m}其中n<=m。最少匹配n次且最多匹配m次。

    70{2,3}是這樣嗎?我們來試試

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "70{2,3}"

    [root@zhuzw-centos6 tmp]# echo $?

    1

    執行錯誤了爲什麼呢?仔細看看元字符你會發現它們基本上都是針對單個字符.

    70{2,3}實際表示的意思應該是700|7000.

    那麼我們如何匹配多個字符呢?這就用到了().

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "(70){2,3}"

    3018002004501202417040707070

    這裏需要注意下\n 匹配的是()裏面的匹配處來的內容而不是裏面的子表達式

    n從外圈開始計算,最外圈的爲1

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "(6(7(\<200\>)))*.*\3?.*[ ]70$"

    30 1800 200 450 120 24 170 40 70 70 70

    389 30 1800 200 450 120 24 1000 40 70

    30 30 1800 200 450 120 24 1000 40 70

    [root@zhuzw-centos6 tmp]# A400=200

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "(6(7(\<`echo A400`\>)))*.*\3?.*[ ]70$"

    30 1800 200 450 120 24 170 40 70 70 70

    389 30 1800 200 450 120 24 1000 40 70

    30 30 1800 200 450 120 24 1000 40 70


2、+和?這兩個元字符其實用法跟{n,m}是一樣的

    +可以寫成{1,}至少出現1次,m不賦值表示無限制,但是不許符合n的要求。

    ?可以寫成{0,1}

    對於 \B  \b \< \>呢你可以把上面字符中被空白字符隔開的一組數字看成是一個單詞。

    \B200\B  \b200\b \<200\> 的區別通過下面的匹配輸出就能對比出來了。

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "\B200\B"

    30120200450122417014080

    7830180020045012241704080

    3018002004501202417040707070

    3893018002004501202410004070

    303018002004501202410004070

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "\b200\b"

    130 120 200 450 12 24 70 140 8000 30

    30 120 200 450 12 24 170 140 80

    78 30 1800 200 450 12 24 170 40 80

    30 1800 200 450 120 24 170 40 70 70 70

    389 30 1800 200 450 120 24 1000 40 70

    30 30 1800 200 450 120 24 1000 40 70

    130120 200 450122470140800030

    [root@zhuzw-centos6 tmp]# cat ceshi | grep -E "\<200\>"

    130 120 200 450 12 24 70 140 8000 30

    30 120 200 450 12 24 170 140 80

    78 30 1800 200 450 12 24 170 40 80

    30 1800 200 450 120 24 170 40 70 70 70

    389 30 1800 200 450 120 24 1000 40 70

    30 30 1800 200 450 120 24 1000 40 70

    130120 200 450122470140800030


匹配一個郵箱地址

郵箱的格式 [email protected]

這是126的郵箱名字規則:6~18個字符,可使用字母、數字、下劃線,需以字母開頭

grep -E "^[[:alpha:]]([a-z]|[A-Z]|[0-9]|[_]){5,17}@([[:alnum:]]+[\.])+[[:alnum:]]+$"

[[:alpha:]]([a-z]|[A-Z]|[0-9]|[_]){5,17}@([[:alnum:]]+[\.])+[[:alnum:]]+\b

字母開頭[[:alnum:]]

可使用字母、數字、下劃線 :([a-z]|[A-Z]|[0-9]|[_])

6~18個字符:{5,17}注意因爲前面已經有開頭的字母佔一位了

@:@ 

郵箱後綴格式126.com :  ([[:alnum:]]+[\.])+[[:alnum:]]+

英文大小寫數字字符至少出現一次,轉義.這個符號;把這兩個字表達式作爲一個組至少出現一次;最後匹配一個英文大小寫數字字符至少出現一次。

分組的原因是可能會有126.com.cn  126.163.com.cn 這種格式的出現

好了寫到這裏正則表達式的筆記和分享暫告一段落。最後呢其實還是大家先去分析下我們的最終目標然後結合語法去寫;目標明確纔好去實現。正則表達式的實現方式有很多種實現的方式也都不一樣不必糾結於簡單複雜,熟練多了自然就簡潔了。


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