正則表達式快速入門_第1頁
正則表達式快速入門_第2頁
正則表達式快速入門_第3頁
正則表達式快速入門_第4頁
正則表達式快速入門_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、教程精選:正則表達式快速入門作者: 開心石頭 出處: 天極網 責任編輯: wenwu 2005-12-02 11:06 【導讀】正則表達式是從左向右去匹配目標字符串的一組模式。大多數(shù)字符在模式中表示它們自身并匹配目標中相應的字符 正則表達式廣泛出現(xiàn)在UNIX/Linux相關的各種領域和多種編程語言里。從常見的shell命令到大名鼎鼎的Perl語言再到當前非常流行的PHP,它都扮演著一個重要的角色。甚至windows的命令行控制臺也支持正則表達式。如果你是一個Linux服務器管理員,你經常會在一些服務器的設置腳本里看到它??梢哉f,它是學好Linux/UNIX必需掌握的一個知識點,否則你連Linu

2、x的啟動腳本都讀不懂。偏偏它又的確有點晦澀難懂,而且相關的資料又大部分是英文,更為它的學習增加了幾多困難。即使有些中文的翻譯資料,不同的譯者對一些術語的譯法也五花八門,讀著讓人平添困惑。為此,我決定為它寫一個簡明教程,盡量可以覆蓋正則表達式涉及到的各主要概念。我并不想把本文寫成一本詳細的正則表達式語法手冊,事實上,這些手冊已經存在了,不過讀起來比較難懂。我希望的是在完成本教程后,你可以比較輕松的讀懂各種工具的正則表達式語法手冊并可以迅速上手,不過要用好正則表達式,可不是一篇短短的教程可以解決的,那是無數(shù)實踐練習的結果。但是,本文的最后一部分對于正則表達式的編寫提出了一些原則性的建議,學習一下這

3、些正則表達式應用先驅者的經驗會讓我們在今后的實踐中少走一些彎路。正則表達式是英文“regular expressions”的譯文,它的產生據(jù)說可以追溯到“神經網絡”等比較高深的理論。那么什么是正則表達式呢?正則表達式是從左向右去匹配目標字符串的一組模式。大多數(shù)字符在模式中表示它們自身并匹配目標中相應的字符。舉個最簡單的例子,模式“The quick brown fox”匹配了目標字符串中與其完全相同的一部分。前面已經提過,正則表達式被許多植根于UNIX/Linux的工具采用,可是這些工具的正則表達式語法并不完全相同,它們中的一些對正則表達式語法的擴展并不被其它工具識別,這也為正則表達式的使用增

4、加了難度。因此,當你在一個具體的環(huán)境中使用正則表達式時,你還要先看一下目標環(huán)境支持的語法范圍,以確保你的正則表達式被正確的解析。在本文中列舉的例子里,我們用正斜線“/”做為模式的定界符(delimiter),一個模式用下面這種格式表示:/A-Z+(abc|xyz)*/I本文將較詳細的闡明下面這些正則表達式概念:模式修正符(modifier),元字符(Meta-characters),子模式(subpatterns)與逆向引用(Back references),重復(Repetition)和量詞(quantifiers),斷言(Assertions),注釋,正則表達式中的遞歸,最后我介紹一款方便

5、學習正則表達式的工具并介紹一些正則表達式編寫的思路。正則表達式的模式修正符(modifier)正則表達式的模式修正符主要用來限定模式與目標字符串的匹配方式,例如是否需要大小寫敏感的匹配,是單行模式還是多行模式。修正符中的空格和換行被忽略,其它字符會導致錯誤。下面列舉一些常見的模式修正符。注意,模式修正符是區(qū)分大小寫的。i:非大小寫敏感模式,:如果設定此修正符,模式中的字符將同時匹配大小寫字母。m:多行模式,當設定了此修正符,“行起始”和“行結束”除了匹配整個字符串開頭和結束外,還分別匹配其中的換行符的之后和之前。s:單行模式,如果設定了此修正符,模式中的圓點元字符(.)匹配所有的字符,包括換行

6、符。沒有此設定的話,則不包括換行符。對于多行模式和單行模式,一個容易讓初學者迷惑的地方是這兩者并不向字面上那樣是互斥的。事實上,它們只是分別定義了英文句點(.)、音調符()和美元符($)這三個元字符的匹配方式,因此,單行模式與多行模式的修正符可以同時使用。x:如果設定了此修正符,模式中的空白字符除了被轉義的或在字符類中的以外完全被忽略,在未轉義的字符類之外的 # 以及下一個換行符之間的所有字符,包括兩頭,也都被忽略。它使得可以在復雜的模式中加入注釋。我們會在后面的部分更詳細的講解正則表達中的注釋。模式修正符還有很多,這里不再一一列舉。我們會結合后面的內容介紹一些其它的模式修正符。不同的工具也可

7、以添加自己的模式修正符,不過上面幾最為常見。模式修正符通常跟在模式定義結束符的后面,例如下面例子中模式最后的“i”字符。/A-Z+(abc|xyz)*/i,這時此修正符會對整個匹配模式起作用。模式修正符也可以在模式內部通過包含在 "(?" 和 ")" 之間的修正符字母序列來實現(xiàn)。例如,(?im) 設定了不區(qū)分大小寫,多行模式。也可以通過在字母前加上減號來取消這些選項。例如組合的選項 (?im-s),設定了不區(qū)分大小寫和多行模式,并取消了單行模式。如果一個字母在減號之前與之后都出現(xiàn)了,則該選項被取消設定。注意,如果(?im-s)出現(xiàn)在一個子模式內(被另一對

8、小括號包含)會把模式修正符的作用局限在該子模式中。正則表達式的元字符(Meta-characters)正則表達式的威力在于其能夠在模式中包含選擇和循環(huán)。它們通過使用元字符來編碼在模式中,元字符不代表其自身,它們用一些特殊的方式來解析。有兩組不同的元字符:一種是模式中除了方括號內都能被識別的,還有一種是在方括號內被識別的。如果想在模式里包含一個元字符本身,就需要用到轉義符號,正則表達式常用反斜線“”作為轉義字符使用,為了匹配“”本身,你需要輸入兩個“”,向這樣“”。當然,這個符號本身也是一個元字符。方括號之外的元字符有這些:有數(shù)種用途的通用轉義符斷言目標的開頭(或在多行模式下行的開頭,即緊隨一換

9、行符之后)$斷言目標的結尾(或在多行模式下行的結尾,即緊隨一換行符之前).匹配除了換行符外的任意一個字符(默認情況下)字符類定義開始字符類定義結束|開始一個多選一的分支(子模式開始)子模式結束?擴展 ( 的含義,我們已經在介紹模式修正符里看到過它的使用。它也可以是 0 或 1 數(shù)量限定符,以及數(shù)量限定符最小值*匹配 0 個或多個的數(shù)量限定符+匹配 1 個或多個的數(shù)量限定符最少/最多數(shù)量限定開始最少/最多數(shù)量限定結束模式中方括號內的部分稱為“字符類”。字符類中可用的元字符為:通用轉義字符排除字符類,但僅當其為第一個字符時有效-指出字符范圍在這里,最值得一提是“”這個元字符。之所以重點對它進行講解

10、是因為這一個元字符有多種不同的用法,在不同情況下代表不同的含義,而且使用頻率非常高,是個很容易讓人迷惑的地方。第一種用法前面我們已經提過,是作為通用轉義字符使用,如果其后跟著一個非字母數(shù)字字符,則取消該字符可能具有的任何特殊含義。此種將反斜線用作轉義字符的用法適用于無論是字符類之中還是之外。例如“”代表一個單獨的反斜線“”。第二種用途提供了一種在模式中以可見方式去編碼不可打印字符的方法。模式中完全可以包括不可打印字符,除了代表模式結束的二進制零,例如,可以用“a”代表alarm,即 BEL 字符(0x07),或用“cx”代表"control-x",其中 x 是任意字符。當然

11、,這種方法表示的不一定非得是不可打印字符,實際上,可以用“xhh(十六進制代碼為 hh 的字符)”和“ddd(八進制代碼為 ddd 的字符)”來以編碼的形式表達任何單字節(jié)字符,例如“040”可以用來表示空格。反斜線的第三個用法是指定通用字符類型,這些字符類型序列可以出現(xiàn)在字符類之中和之外。每一個匹配相應類型中的一個字符。如果當前匹配點在目標字符串的結尾,以上所有匹配都失敗,因為沒有字符可供匹配。有以下這些常見的通用字符類:d 任一十進制數(shù)字D任一非十進制數(shù)的字符s任一空白字符S任一非空白字符w任一“字”的字符W任一“非字”的字符反斜線的第四個用法是某些簡單的斷言,關于斷言的討論我們放在后面,這

12、里先不加討論。反斜線的最后一個用法是逆向引用。關于逆向引用,我們會在后面討論逆向引用的部分來做進一步的討論。我們已經看到,反斜線的眾多用法,其中一些涉及到了以后才講的內容。我們在模式中遇到反斜線時一定要注意它具體是哪一種用途以免疑惑。另外兩個方括號也是非常重要的元字符,左方括號開始了一個字符類,右方括號結束之。單獨一個右方括號不是特殊字符。字符類匹配目標中的一個字符,該字符必須是字符類定義的字符集中的一個;除非字符類中的第一個字符是音調符(),此情況下目標字符必須不在字符類定義的字符集中。如果在字符類中需要音調符本身,則其必須不是第一個字符,或用反斜線轉義。例如,A-Z表式非大寫字符。其它元字

13、符我們會在以后的文章中結合相關內容介紹。在上篇文章里,我們介紹了正則表達式的模式修正符與元字符,細心的讀者也許會發(fā)現(xiàn),這部分介紹的非常簡略,而且很少有實際的例子的講解。這主要是因為網上現(xiàn)有的正則表達式資料都對這部分都有詳細的介紹和眾多的例子,如果覺得對前一部分缺乏了解可以參看這些資料。本文希望可以盡可能多涉及一些較高級的正則表達式特性。在本文里,我們主要介紹子模式(subpatterns),逆向引用(Back references)和量詞(quantifiers),其中重點介紹對這些概念的一些擴展應用,例如子模式中的非捕獲子模式,量詞匹配時的greedy與ungreedy。子模式(subpat

14、terns)與逆向引用(Back references)正則表達式可以包含多個字模式,子模式由圓括號定界,可以嵌套。這也是兩個元字符“(”和“)”的作用。子模式可以有以下作用:1. 將多選一的分支局部化。例如,模式: cat(aract|erpillar|)匹配了 "cat","cataract" 或 "caterpillar" 之一,沒有圓括號的話將匹配 "cataract","erpillar" 或空字符串。2. 將子模式設定為捕獲子模式(例如上面這個例子)。當整個模式匹配時,目標字符串中匹

15、配了子模式的部分可以通過逆向引用進行調用。左圓括號從左到右計數(shù)(從 1 開始)以取得捕獲子模式的數(shù)。注意,子模式是可以嵌套的,例如,如果將字符串 "the red king" 來和模式 /the (red|white) (king|queen)/進行匹配,捕獲的子串為 "red king","red" 以及 "king",并被計為 1,2 和 3 ,可以通過“1”,“2”,“3”來分別引用它們,“1”包含了“2”和“3”,它們的序號是由左括號的順序決定的。在一些老的linux/unux工具里,子模式使用的圓括號需要

16、用反斜線轉義,向這種(subpattern),但現(xiàn)代的工具已經不需要了,本文中使用的例子都不進行轉義。在上文里,我們介紹了正則表達式的子模式,逆向引用和量詞,在這篇文章里,我們將重點介紹正則表達式中的斷言(Assertions)。斷言(Assertions)斷言(Assertions)是在目標字符串的當前匹配位置進行的一種測試但這種測試并不占用目標字符串,也即不會移動模式在目標字符串中的當前匹配位置。讀起來似乎有點拗口,我們還是舉幾個簡單的例子。兩個最常見的斷言是元字符“”和“$”,它們檢查匹配模式是否出現(xiàn)在行首或行尾。我們來看這個模式/ddd$/,試著用它來匹配目標字符串“123”?!癲dd

17、”表示三個數(shù)字字符,匹配了目標字符串的三個字符,而模式中的和$分別表示這三個字符同時出現(xiàn)在行首和行尾,而它們本身并不與目標字符串中的任何字符相對應。其它還有一些簡單的斷言b, B, A, Z, z,它們都以反斜線開頭,前面我們已經介紹過反斜線的這個用法。這幾個斷言的含義如下表。斷言含義b字分界線B非字分界線A目標的開頭(獨立于多行模式)Z目標的結尾或位于結尾的換行符前(獨立于多行模式)z目標的結尾(獨立于多行模式)G目標中的第一個匹配位置注意這些斷言不能出現(xiàn)在字符類中,如果出現(xiàn)了也是其它的含義,例如b在字符類中表示反斜線字符0x08。前面介紹的這些斷言的測試都是一些基于當前位置的測試,斷言還支

18、持更多復雜的測試條件。更復雜的斷言以子模式方式來表示,它包括前向斷言(Lookahead assertions)和后向斷言(Lookbehind assertions)。前向斷言(Lookahead assertions)前向斷言從目標字符串的當前位置向前測試斷言條件是否成立。前向斷言又可分為前向肯定斷言和前向否定斷言,分別用(?=和?!表示。例如模式/ w+(?=;)/用來表示一串文本字符后面會有一個分號,但是這個分號并不包括在匹配結果中。一件有趣的事看起來差不多的模式/ (?=;)w+/并不是表示一串前面不是分號的alpha字符串,事實上,不論這串alpha字符的前面是否是一個分號它總是匹

19、配的,要完成這個功能需要我們下面提到的后向斷言(Lookbehind assertions)。后向斷言(Lookbehind assertions)后向斷言分別用(?<=和(?<!表示肯定的后向斷言與否定后向斷言。例如,/ (?<!foo)bar/將尋找一個前面不是foo的bar字符串。一般而言,后向斷言使用的子模式需要有確定的長度值,否則會產生一個編譯錯誤。 使用后向斷言與一次性子模式搭配使用可以有效的文本的結束部分進行匹配,這里來看一下例子??紤]一下如果用/abcd$/這樣一個簡單的模式來匹配一長段以abcd結尾的文本,因為模式的匹配過程是從左向右進行的,正則表

20、達式引擎將在文本中尋找每一個a字符并嘗試匹配剩余的模式,如果在這長段文本里僅好有不少的a字符,這樣做明顯是非常低效的,而如果把以上模式換成為樣/.*abcd$/,這時前面的“.*”部分將匹配整個文本,然后它發(fā)現(xiàn)下一個模式a無法匹配,這時會發(fā)生前面提到過的回溯過程,解析器會逐次縮短“.*”匹配的字符長度從右向左逐次查找剩余的子模式,也要產生多次的嘗試過程?,F(xiàn)在,我們用一次性子模式與后向斷言重寫所用的模式,改為/(?>.*)(?<=abcd)/,這時,一次性子模式一次匹配了整段文本,然后用后向斷言檢查前面四個字符是否為abcd,只需要一次檢測就可以立刻確定整個模式是否匹配。在遇到需要匹

21、配一個很長的文本時,這種方法可以非常顯著的提高處理效率。一個模式中可以包含多個相繼的斷言,斷言也可以嵌套。另外,斷言使用的子模式也是非捕獲的,不能被逆向引用。斷言的一個重要應用領域就是做為條件子模式的條件。那什么是條件子模式呢?在上一篇文章里,我們介紹了正則表達式中斷言相關的一些概念,在本文里,我們會介紹正則表達式中遞歸的運用與利用正則表達式修改目標字符串。正則表達式中的遞歸接觸過程序的朋友可能都遇到過成對的各種括號吧,這些括號常常相互嵌套,而且嵌套的層次數(shù)目無法確定。試想一下如果想提取一段程序里用括號括起的一段代碼,這里面很可能包含了層次數(shù)目不定的其它括號對,用正則表達式該如何完成?在Per

22、l 5.6之前這的確有點困難,不過從Perl 5.6之后,引入了遞歸正則表達式,這個問題得到了解決。通常在正則表達式里用“(?R)”表示一個對自己的引用,下面讓我們看看用什么正則表達式來解決剛才提出的問題。/( ( (?>()+) | (?R) )* )/x現(xiàn)在讓我們來分析這個模式的含義,這里使用了“x”模式修正符,以便可以在模式中加入空格以方便閱讀。模式的開頭是匹配第一個左圓括號,然后我們需要捕獲的子模式,注意,字模式后面跟了量詞“*”,表示此模式可以重復0到多次。最后是一個結束圓括號?,F(xiàn)在我們分析子模式( (?>()+) | (?R) )的內容。這是一個分支子模式,表示模式可以有兩種情況,第一種是(?>()+),這是一個一次性子模式,代表一個以上的非括號字符,另一種情況是| (?R),也即對正則表達式自己的遞歸調用( ( (?>()+) | (?R) )* ),又尋找一個左圓括號,開始查找一對嵌套的圓括號包含的內容。分析到這里,這個正則

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論