全面分析Linux正則表達式(三)
Linux正則表達式的模式修正符與元字符在前面兩篇我們已經介紹了,因為網上現有的正則表達式資料都對這部分都有詳細的介紹和眾多的例子,如果覺得對前一部分缺乏了解可以參看這些資料。本文希望可以盡可能多涉及一些較高級的正則表達式特性。
在本文里,我們主要介紹Linux正則表達式的子模式(subpatterns),逆向引用(Back references)和量詞(quantifiers),其中重點介紹對這些概念的一些擴展應用,例如子模式中的非捕獲子模式,量詞匹配時的greedy與ungreedy。
子模式(subpatterns)與逆向引用(Back references)
正則表達式可以包含多個字模式,子模式由圓括號定界,可以嵌套。這也是兩個元字符“(”和“)”的作用。子模式可以有以下作用:
1. 將多選一的分支局部化。
例如,模式: cat(aract|erpillar|)匹配了 "cat","cataract" 或 "caterpillar" 之一,沒有圓括號的話將匹配 "cataract","erpillar" 或空字符串。
2. 將子模式設定為捕獲子模式(例如上面這個例子)。當整個模式匹配時,目標字符串中匹配了子模式的部分可以通過逆向引用進行調用。左圓括號從左到右計數(從 1 開始)以取得捕獲子模式的數。
注意,子模式是可以嵌套的,例如,如果將字符串 "the red king" 來和模式 /the ((red|white) (king|queen))/進行匹配,捕獲的子串為 "red king","red" 以及 "king",并被計為 1,2 和 3 ,可以通過“1”,“2”,“3”來分別引用它們,“1”包含了“2”和“3”,它們的序號是由左括號的順序決定的。
在一些老的linux/unux工具里,子模式使用的圓括號需要用反斜線轉義,向這種(subpattern),但現代的工具已經不需要了,本文中使用的例子都不進行轉義。
非捕獲子模式(non-capturing subpatterns)
用一對括號同時完成上面提到的子模式的兩個功能有時會出現一些問題,例如,由于逆向引用的數目是有限的(通常***不超過9),而且經常會遇到無需捕獲的子模式定義。這時,可以在開始的括號后加上問號和冒號來表示這個子模式無需捕獲,就向下面這樣:((?:red|white) (king|queen))。
如果將“the white queen”作為模式匹配的目標字符串,則捕獲的字串有“white queen”和“queen”,分別作為“1”和“2”,white雖然符合子模式“(?:red|white)”,但并不被捕獲。
我們前面已經介紹過用括號與問號表示模式修正符的方法,為方便起見,如果需要在非捕獲子模式中插入模式修正符,可以把它直接放在問號和冒號之間,例如,下面兩個模式是等效的。
/(?i:saturday|sunday)/和/(?:(?i)saturday|sunday)/。
逆向引用(Back references)
前面介紹反斜線作用時,已經提到它的一個作用就是表示逆向引用,當字符類之外的反斜線后跟一個大于0的十進制數時,它很有可能是一個逆向引用。它的含義正如它的名稱如言,它表示對它出現之前已經捕獲的子模式的引用。這個數字代表了它引用的左括號在模式中出現的次序,我們在介紹子模式時已經看到過逆向引用的一個例子,那里的過“1”,“2”,“3”分別表示所捕獲的***,第二,和第三個小括號定義的子模式的內容。
值得注意的是,當反斜線后的數字小于10時,可以確定此為一個逆向引用,這樣,這個逆向引用就可以出現在之前有相應數目的左圓括號被捕獲前而不會出現混淆,只有整個模式能提供那么多的捕獲子模式,就不會報錯。說起來似乎很混亂,還是讓我們來看下面這個例子。把介紹子模子時舉的例子拿來修改一下,前面講過字符串 "the red king" 來和模式 /the ((red|white) (king|queen))/匹配,捕獲的子串為 "red king","red" 以及 "king",并被計為 1,2 和 3 ,現在把字符串,修改為" king,the red king",模式改為/3,the ((red|white) (king|queen))/,這個模式應該也是可以匹配的。不過,并非所有的正則表達式工具都支持這種用法,安全的做法是在相應序號的左括號之后使用與之相關的逆向引用。
需要注意的另一點是逆向引用的值是在目標字符串中實際捕獲的符合子模式的字符串片段而非該子模式本本身。例如/ (sens|respons)e and 1ibility/會匹配“sense and sensibility” 和 “response and responsibility”,但不會是 "sense and responsibility"。當被逆向引用的子模式后面有量詞從而被重復匹配了多次,逆向引用的值會以***一次匹配的值為準。例如/([abc]){3}/匹配字符串“abc”時,逆向引用“1”的值將是***一次匹配的結果“c”。
相信這里大家對Linux正則表達式的子模式(subpatterns)與逆向引用(Back references)已經有所了解了,后面還有更精彩內容。
【編輯推薦】