正則表達式的基本用法


Perl 有很多其它語言所沒有的特性,這其中對正則表達式(regular expression)的強大支持是它最為突出的一個亮點。正則表達式使得 perl 在處理文本時具有非常強大的優勢:快速,靈活而且很可靠,甚至可以說,強大文本處理能力,是 perl 在眾多語言中最為閃耀的一個特點。  因此學習 perl 的過程,必然也是學習正則表達式的過程,這或許多少給 perl 的學習增加了些少的負擔,但好在正則表達式並不是 perl 所獨有的, 它是一門使用非常廣泛的語言,在很多工具及其它編程語言中都有廣泛的支持,比如:grep,awk,sed,vi 等。  它是如此的常見,以致於編程人員在很多場合都無可避免的要與之打交道,因此掌握好正則表達的好處是非常明顯的,好在它的語法也很簡單,學習起來也不算太難。

在 Perl 或其它一些語言及工具中,正則表達式通常也會叫為“模式"(pattern),正則表達式本質上來說是一個字符串模板,用來確認某個字符串是否符合這個模板的格式,任何一個字符串,要么符合這個模板,要么不符合這個模板。具體到在Perl中,正則表達式是用"/"圍起來的,比如:($string =~ /pattern/)。在這里我們暫且稱 string 為匹配串,只有當 string 匹配了 ”pattern" 這個串時,這個表達式才是true,反之為false。如: "abc ef ffff" =~ /ef/ 為 true,"abc" =~ /ee/ 為 false。

當然上面的例子只是最簡單的情形,如果正則表達式只能做這樣單純的純字符匹配,那它就不可能這么強大。正則表達式通過一類特殊的字符,我們稱為元字符或通配符(meta character)來進行字符的模糊表示,它們在匹配的過程中代表特殊的含義。下面我們就進行簡單的介紹。

(1) 點號(.),它用來匹配任意一個單字符(\n 排除在外,后面我默認不再提這個例外)。

        所以: "twoon" =~ /tw.on/   為 true

                  “twvon" =~ /tw.on/   也為 true.

        點號在正則表達式中是有特殊含義的,有時我們可能也要匹配點號,這時就需要轉義一下。

        "twoo.n" =~ /twoo\.n/    為true.

        正則表達中,所有其它的通配符也都可以用同樣的方式進行轉義,表示直接匹配通配符,去除它的特殊含義。

        你可以看到\也是一個通配符,如果要匹配它也是同樣的道理。

        "two\\on" =~ /two\\on/ 為true.

 

(2) 星號(*) : 星號代表匹配它前面一個字符任意遍(0或任意次),它是一數量詞(quantifier),必須跟在其它字符的后面,否則這個表達式不正確。

        如: ”twoon" =~ /two*n/      為true

              “twn"     =~ /two*n/     也為true.

               "twoon" =~ /*twoon/   表達式不正確,*必須跟在其它符號后面.

       同時星號也可以匹配點號(.),點號代表任意非回車字符,因此, (.*)就代表任意字符任意次。這是一個慣常的用法,如:   /twoon.*walks/    能匹配任意包含"twoon"在前,"walks“在后的字符串。所以(.*)也被稱為:any old junk. 匹配任何東西。 

   

(3) 加號(+): 加號是一個與星號(*)類似的通配符,它也是數量詞,表示匹配前面的字符一次或多次(至少一次).

       它與星號的差別就在這里,星號可以匹配0次,加號則必須一次以上。  

        如:"twoon" =~ /two+n/ 為true.

              "twn"    =~ /two+n/ 為false.

   

(4) 問號(?): 問號也是一個數量詞,它代表匹配前一個字符0或1次。

        如: "twoon" =~ /twoo?n/ 為true

               "twoon” =~ /two?n/ 為false.

               "twn"   =~ /two?n/ 為true.

   

(5) 括號(()): 括號用來表示一個組合,前面我說數量詞作用在前一個字符上,這個說法事實上不准確,應該說是作用在一個組合上,一個字符是一個組合,但多個字符也可以成為組合。括號就是用來表示一個組合,被括號括起來的就是一個組合。

        如: "twoon" =~ /tw(o)*n/ 為true.

              "twoon" =~ /tw(oo)*n/ 為true

             "twowon" =~ /t(wo)*n/ 為true.

              "twoon" =~ /t(wv)*oon/ 為false.

               “twoon" =~ /t(wo)+on/為true.

               "twon"   =~ /t(wo)+on/為false.

     括號里可以放置任何字符,也可以放置其它通配符,如  "aaabcc" =~ /(aa+b)?cc/

     

(6) 引用通配符:反斜杠加上數字是所謂引用通配符(back reference): \1 \2 \3 等,它的作用是引用前面的某個括號元組,如:  

          "twoonwo" =~ /t(wo)on\1/   為true

    乍看起來,似乎作用不明顯,如上例,我們完全可以不用\1,而寫成這樣: /t(wo)on(wo)/

    在上面的例子里,這個質疑是可以理解的。但有時,我們的括號元組可能這樣寫的:  (we...) 因為點號代表任意字符,如果我們后面要作用這個元組,不用引用通配符, 我們根本無法引用,具體看例子:    

          ”weabceeweabc" =~ /(we...)ee\1/  為 true。

          “weabceeweabc" =~ /(we...)ee(we...)/ 為 true

          ”weabceewecdf" =~ /(we...)ee(we...)/  也為 true.

    從第2,3個例子,我們可以看區別。\1 表示的是與前一個元組完全一樣的匹配。而 \1,\2,\3等,則分別表示,從左往右數第幾個元組。

          “abcdef def abc" =~ /(...)(...) \2\1/ 為 true.

    在 perl 中,引用通配符中支持從1~9,寫法上很活,你既可直接\1 \2 ...\9這樣來寫,也可以寫成 \g{1]  ,\g{2},.....\g{9}。后面一種寫法相對復雜些,但有助於perl來理解你想表達的含義。因為反斜杠在程序語言中有特殊的信念,通常表達轉義,perl 在遇到反斜杠時,它會去猜你想表達的什么。所以如果你寫一個類似: \123這樣的東西,它就不知怎么去解析,你是想表達 \1+23,引用后面跟着數字,還是,\12+3,或 \123,轉義符后面跟數字是可以表示轉義一個8進制數字的。因此這里產生了歧義。perl 5.10 於是引入了 \g{N}這種表述方式來表示引用通配符。N 甚至可以是負數,當是用負數是,它表示一個相對位置。表示從當前位置開始往左數,第N個元組,如:

           "twooavvboonn"  =~ /tw(oo)a(vv)b\{-2}(nn)/   為true.

   

(7) 中括號[]: 中括號用來表示一個字符集合(character set)

     字符集合,顧名思義,就是字符的集合,集合的元素放在中括號里,表示每次匹配中其中的一個,如: "twoon” =~ /[tw]woo/ 為 true

     有時如果這個集合有很多元素,如26個字母,數字等,一個個地寫在中括號里,未免太麻煩太蠢笨,這時可以用連字符(hyphen)來表示一個范圍,如:[a-z]表示小寫字母的集合,[a-zA-Z]表示大小寫字母的集合。

     上面的用法用於提供范圍來選擇,但有時不匹配某個范圍也是很常見的匹配需求,這時我們可以在集合的開頭放一個脫字符 ^ (caret). 這種寫法表示,匹配任何不在該集合中的字符,與上面的用法剛好相反。如:"twoon" =~ /[^two]woon/ 為false

               “ewoon" =~ /[^two]woon/ 為true

      由上面的用法,可知 ^,- 這兩種符號在集合中有特殊含義,如果我們們想在集合中表示這兩個字符,就也要轉義一下。如:[\^ab\-]

      有些字符集合是很常用的,如字母,數字等,perl提供了一些縮寫來表示這些常用的集合,如:\d表示一個數字,等價於[0-9],這些特殊字符包括如下 :

        \w -- (小寫w) 表示字母或數字,等價於 [a-zA-Z0-9]

        \W -- (大寫W)非字母且非數字,與\w相反

        \s  --  (小寫s)匹配一個空格字符,包括:空格,換行,回車,tab,等價於[ \n\r\t\f]

        \S --  (大寫S)匹配非空格字符,\s的相反

        \d -- 表示10進制數字,等價於 [0-9]

 

(8) 大括號:{}  

   大括號的作用是指定重復前面一個字符多少遍:

   {N} 重復N遍

   {n,m} 重復 n~m 遍

   {n,}  至少重復n遍

   {,m} 至多重復m遍

 示例:"twoon" =~ /two{2}n/    為true.

    

(9) ^,& 這兩個通配符用來表示在匹配串的頭部或尾部匹配。

     一般我們寫這種: "twoon" =~ /oo/ 正則表達式的時候,匹配是從"twoon"的開始一路匹配下去,如tw != oo,就繼續往下匹配,但有時候我們可能只想匹配一下開頭或結尾,這時^,&就派上用場了。^用於匹配字符串的開關,&用於匹配字符串的結尾。如:  "twoon" =~ "^tw"  為true.

            “twoon” =~ “oo"   為true

            "twoon" =~ "^oo" 就為false.

            ”twoon" = "on&"  為true.

            "twoon“ = ”oo&"  為false

 

(10) “或" 通配符:  正則表達式用豎線 | 表示或, (ab | cd) 表示匹配豎線左右的字符組之一,如果左右的字符數超過一個,它必須和括號一起使用。

        如:    "twoon” =~ /t|ewoon/   結果為true

                    "twoon" =~ /(tw|ee)oon/  結果為true

                    "twoon" =~ /(ee|gs)oon/   結果為false

          

上面簡單地介紹了正則表達式中各種通配符的含義及用法,可以看出,正則表達式在語法上還算是簡單的,但這並不代表它也只會做簡單的事情,事實上,正則表達式也可以寫得很復雜,語法的簡單或復雜與該語言功能強大與否並沒有太多直接的聯系。學習正則表達式可以讓我們在很多場合下受益,特別是在使用unix類系統下的各種工具時,只是這種語言也和很多其它很多語言一樣,學而不用就很容易忘。本文只是簡單的介紹了一下它的基本語法,基本寫法,要想做到熟能生巧,就需要在日常工作中,多練習,多操作,多留心了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM