青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

教程精選:正則表達式快速入門(二)

作者:開心石頭
  在上篇文章里,我們介紹了正則表達式的模式修正符與元字符,細心的讀者也許會發現,這部分介紹的非常簡略,而且很少有實際的例子的講解。這主要是因為網上現有的正則表達式資料都對這部分都有詳細的介紹和眾多的例子,如果覺得對前一部分缺乏了解可以參看這些資料。本文希望可以盡可能多涉及一些較高級的正則表達式特性。

  在本文里,我們主要介紹子模式(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”。

  命名子模式(named subpattern)

  一些工具(例如Python)可以為逆向引用命名,從而定義出命名子模式。在Python中對正則表達式的使用是以函數或方法調用的格式,語法與這里舉的例子有較大差別。有興趣的朋友可以參看一下自己使用的工具來看看是否支持命名子模式。

  重復(Repetition)和量詞(quantifiers)

  在前面介紹逆向引用的部分里我們已經接觸到了量詞(quantifiers)的概念,例如前面的例子/([abc]){3}/表示三個連續的字符,每個字符都必然是 “abc”這三個字符中的一個。在這個模式里,{3}就屬于量詞。它表示一個模式需要重復匹配(repetition)的數目。

  量詞可以放在下面這些項目之后:

  ?●單個字符(有可能是被轉義的單個字符,如\xhh)

  ?●“.”元字符

  ?● 由方括號表示的字符類

  ?● 逆向引用

  ?●由小括號定義的子模式(除非它是個斷言,我們會在以后介紹)

  最通用的量詞使用形式是用花括號括起的兩個由逗號分隔的數字,如這樣的格式{min,max},例如,/z{2,4}/ 可以匹配 "zz", "zzz", 或者 "zzzz",花括號中的最大值以及前面的逗號可以省略,例如/\d{3,}/可以匹配三個以上的數字,數字的數目沒有上限,而/\d{3}/(注意,沒有逗號)則精確的匹配3個數字。當花括號出現在不允許量詞的位置或者語法與前面提到的不符時,這里它僅僅代表花括號字符本身而不再具有特殊的含義。例如{,6}不是量詞,它僅僅代表這四個字符本身的含義。

  為了方便,三個最常用的量詞有它們的單字符縮寫形式,它們的的含義如下表:

*
相當于 {0,}
+
相當于 {1,}
?
相當于 {0,1}

  這也是以上三個元字符做為量詞使用含義。

  在使用量詞特別是沒有上限限制的量詞時,應該特別注意不要構成無限循環,例如/(a?)*/,在有的正則表達式工具里。這會形成一個編譯錯,不過有的工具卻允許這種結構,但不能保證各種工具都可以很好的處理這種結構。

 

 

  量詞匹配的“greedy”與“ungreedy”

  在使用帶量詞的模式時,我們常會發現對同一模式而言,同一個目標字符串可以有多種匹配方式。例如/\d{0,1}\d/,可以匹配兩個或三個十進制數字,如果目標字符串是123,當量詞取下限0里,它匹配“12”,當量詞取上限1里,它匹配“123”整個字符。這兩種匹配結果都是正確的,如果我們取它的子模式/(\d{0,1}\d)/,則匹配的結果\1到底是“12”還是“123”?

  實際的運行結果一般會是后者,因為默認情況下,大多數正則表達式工具的匹配是按“greedy”原則匹配的。“greedy”單詞的中的含義是“貪吃的, 貪婪的”的意思,它的行為也如此單詞的含義,所謂greedy匹配意指在量詞限制范圍內,只要能保持后續模式的匹配,匹配總是盡可能的重復下去,直到不匹配的情況發生為止。為便于理解,我們看下面這個簡單的例子。

  /(\d{1,5})\d/匹配“12345”這個字符串,這個模式表示在1到5個數字后面跟上一個數字,量詞范圍從1到5,當它的值在1-4時,整個模式都是匹配的,\1的值可以是“1”,“12”,“123”,“1234”,而在greedy匹配的情況下,它取匹配時的量詞最大值,因此最終匹配的結果是”1234”。

  在大多數情況下,這就是我們想要的結果,但情況并不總這樣。例如,我們希望用下面這個模式提取出c語言的注釋部分(在c語言中,注釋語句放在字符串/*和*/之間)。我們使用的正則表達式是/\*.*\*/,但匹配的結果卻完全和需要的不同。當正則表達式解析到“/\*”這后的“.*”時,因為“.”可以代表任意字符,這也包含了其后需要匹配的“*/”,在量詞的作用下,這個匹配將一直進行下去,超過下一個“*”/直到文本的結束,這顯然不是我們需要的結果。

  為了完成如上例我們想要的那種匹配,正則表達式引入了ungreedy匹配方法,與greedy匹配相反,在滿足整個模式匹配的前提下,它總是取最小的量詞數目結果。Ungreedy匹配用在量詞后面加上問號“?”來表示。例如在匹配C語言的注釋時,我們把正則表達式寫成如下形式:/\*.*?\*/,在量詞“*”后加上問號就可以達成想要的結果。還有前面那個例子用/(\d{1,5})\d/匹配“12345”這個字符串,如果改寫為ungreedy模式向這樣/(\d{1,5}?)\d/,、\1的值將為1。

  上面的解釋也許有些不準確,量詞后的問號的作用實際上是反轉當前的正則表達式的greedy與ungreedy行為。你可以通過模式修正符“U”將正則表達式設成ungreedy模式然后在模式中通過量詞后的問號將之反轉為greedy。

  一次性子模式(Once-only subpatterns)

  關于量詞的另一個有趣的話題是一次性子模式(Once-only subpatterns)。要理解它的概念需要先了解一下含有量詞的正則表達式的匹配過程。我們這里舉個例子。

  現在,讓我們用模式/\d+foo/來匹配字符串“123456bar”,當然,它的結果是沒有匹配。但正則表達式引擎是如何工作的呢?它先分析前面的\d+,這代表一個以上的數字,然后檢查目標字符串的對應位置的第一個字符“1”,符合模式,然后根據量詞重復這個模式對字符串進行匹配直到“123456”始終符合“\d+”模式,接著它在目標字符串中遇到字符“b”無法與“\d+”匹配,于是查看“\d+”的后續模式“foo”,與目標字符串的后續部分“bar”無法匹配,這時,有趣的事情出現了,解釋引擎會對前面已經解析過的“\d+”模式進行回溯,將量詞數目減少一,看剩余部分能否匹配,此時“\d+”的值改為“12345”,然后解釋引擎看目標字符串剩余的部分“6bar”能否與剩余的模式“foo”相匹配,如果不行,就把量詞數再減一,直到達到最小的量詞限制,如果仍無法匹配,則表明目標字符串無法匹配,返回無法匹配的結果。

  現在,我們就可以來接觸一次性子模式了。所謂一次性子模式就是定義在正則表達式解析時不需要上述回溯過程的子模式。它用左圓括號后面的問號和小于號來表示,向這樣(?>)。如果將上面提到的例子改為一次性子模式,可以這樣書寫:

  /(?>\d)+foo/,這時,當解析器遇到后面不匹配的bar時,會立即返回不匹配的結果,而不會進行前面提到的回溯過程。

  需要了解的是,一次性子模式屬于非捕獲子模式,它的匹配結果不能被逆向引用。

  當一個沒有設定重復上限的子模式中包含了同樣沒有設定重復上限的模式時,使用一次性子模式是唯一可以避免讓你的程序陷入長時間等待的方法。例如你用“/(\D+|<\d+>)*[!?]/”這個模式去匹配一長串的a字符,向這樣“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa”,在返回最終無匹配的結果前,你會等待很長的一段時間。這個模式表示一串非數字字符或者用尖括號括著的一串數字后跟隨著嘆號或者問號,把這段字符串分成兩個重復的部分會有很多種分法,而無論是子模式本身還是子模式之內的量詞的各可能值都要經過逐一測試,這將使最終的運算量達到一個很大的程度。這樣,你將在電腦前等待相當長的時間才會看到結果。而如果用一次性子模式來改寫剛才的模式,改成這樣/ ((?>\D+)|<\d+>)*[!?]/,你就可以很快得到運算的結果。

  未完等續

posted on 2007-04-22 17:14 PeakGao 閱讀(380) 評論(0)  編輯 收藏 引用 所屬分類: php

<2007年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

導航

統計

常用鏈接

留言簿(9)

隨筆分類(67)

隨筆檔案(65)

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲高清电影| 国产精品乱码久久久久久| 久久青草欧美一区二区三区| 午夜精品久久久99热福利| 亚洲视频图片小说| 亚洲日本中文字幕区| 欧美日韩中文另类| 欧美视频不卡中文| 国产精品综合av一区二区国产馆| 国产午夜精品全部视频播放| 影音先锋国产精品| 亚洲最新视频在线| 欧美专区在线| 欧美护士18xxxxhd| 在线视频你懂得一区二区三区| 亚洲综合色婷婷| 免费观看成人网| 国产精品久久久久毛片大屁完整版 | 国产精品亚洲а∨天堂免在线| 国产精品午夜在线| 最新国产成人av网站网址麻豆| 亚洲少妇最新在线视频| 久久人人爽人人爽爽久久| 亚洲精品乱码久久久久久黑人 | 亚洲欧美日韩在线高清直播| 性欧美暴力猛交69hd| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲国产视频一区二区| 猛男gaygay欧美视频| 99国产欧美久久久精品| 久久久久se| 欧美色区777第一页| 精品成人a区在线观看| 中文欧美字幕免费| 欧美国产日韩一区二区| 亚洲在线视频免费观看| 美日韩免费视频| 国产欧美日韩免费| 这里是久久伊人| 欧美激情精品久久久久久大尺度| 亚洲欧美在线另类| 国产精品a久久久久| 狠狠色综合色综合网络| 午夜免费在线观看精品视频| 亚洲国产成人av好男人在线观看| 欧美一区二区三区成人 | 亚洲承认在线| 久久久久高清| 午夜亚洲影视| 国产欧美一区二区白浆黑人| 亚洲午夜极品| 一区二区电影免费观看| 欧美黄色成人网| 91久久嫩草影院一区二区| 免费国产一区二区| 久久久久久免费| 影音先锋日韩精品| 久久精品国产久精国产爱| 亚洲无亚洲人成网站77777| 欧美日韩一级黄| 9色国产精品| 亚洲精品中文字幕在线| 欧美精品色网| 亚洲天堂av图片| 99在线|亚洲一区二区| 老司机午夜精品视频在线观看| 国产精品最新自拍| 久久成人免费| 久久国产福利| 在线国产精品播放| 欧美国产日韩亚洲一区| 欧美韩日一区二区三区| 一本色道久久综合| 宅男精品视频| 国内外成人免费激情在线视频网站| 久久免费少妇高潮久久精品99| 欧美一级成年大片在线观看| 黄色在线一区| 亚洲国产精品成人久久综合一区| 欧美成人a视频| 亚洲综合99| 欧美中文字幕视频| 亚洲狼人综合| 亚洲欧美日韩网| 亚洲一区日本| 亚洲高清视频在线观看| 亚洲精品久久| 国产精品人成在线观看免费| 久久女同互慰一区二区三区| 欧美黄免费看| 久久久久久黄| 欧美日韩久久精品| 久久全国免费视频| 欧美日韩中国免费专区在线看| 欧美专区在线观看| 欧美精品在线极品| 久久九九国产| 欧美色道久久88综合亚洲精品| 国户精品久久久久久久久久久不卡| 亚洲香蕉网站| 亚洲精品你懂的| 免费不卡亚洲欧美| 亚洲视频一区二区免费在线观看| 亚洲欧美激情视频| 国产精品久久久久国产a级| 中国亚洲黄色| 麻豆精品在线播放| 一本色道久久精品| 宅男噜噜噜66国产日韩在线观看| 亚洲专区在线视频| 亚洲免费高清视频| 久久精品30| 午夜亚洲一区| 欧美大片一区二区| 久久免费国产精品| 国产精品主播| 日韩亚洲精品电影| 亚洲日本成人网| 久久久久久网| 久久久久国产一区二区三区四区 | 亚洲国产三级网| 先锋影院在线亚洲| 午夜国产不卡在线观看视频| 欧美精品一区三区| 欧美激情第9页| 在线精品一区二区| 久久久久久999| 久久精品国产第一区二区三区| 国产精品欧美激情| 亚洲综合999| 午夜影院日韩| 国产日韩成人精品| 欧美一区久久| 亚洲国产91精品在线观看| 亚洲国产一区二区在线| 在线不卡视频| 久久婷婷国产麻豆91天堂| 久久伊人免费视频| 国产欧美一区二区白浆黑人| 一本久久知道综合久久| 欧美激情综合色| 亚洲精品国产品国语在线app| 亚洲黄一区二区| 牛牛影视久久网| 亚洲国产精品国自产拍av秋霞| 樱桃成人精品视频在线播放| 久久久精品国产免大香伊| 美女91精品| 美女精品在线| 欧美激情第9页| 欧美视频一区二区三区四区| 欧美视频在线观看一区二区| 欧美日韩高清在线| 欧美午夜不卡视频| 国产一区二区三区四区在线观看| 国产精品红桃| 亚洲国产精品成人一区二区| 欧美成ee人免费视频| 欧美成人第一页| 日韩视频精品在线观看| 亚洲男同1069视频| 国产一区二区高清不卡| 久久综合婷婷| 亚洲精品乱码久久久久久日本蜜臀 | 欧美日韩免费高清| 亚洲最新色图| 欧美在线观看视频一区二区| 激情成人av| 欧美黄色视屏| 性做久久久久久久免费看| 欧美激情1区2区3区| 亚洲男同1069视频| 亚洲精品久久7777| 国产欧美日韩视频在线观看| 老司机成人在线视频| 亚洲天堂黄色| 亚洲福利久久| 久久精品99久久香蕉国产色戒| 亚洲国产视频一区| 国产女主播在线一区二区| 久热精品视频在线| 亚洲一区二区在| 亚洲欧洲另类国产综合| 久久久久久精| 香蕉久久夜色精品国产使用方法| 亚洲黄色在线看| 国产在线成人| 国产精品一香蕉国产线看观看| 欧美不卡视频一区| 久久久久久久久久久一区| 亚洲一区精品在线| 一区二区免费在线视频| 欧美大片va欧美在线播放| 久久精品99无色码中文字幕| 亚洲伊人第一页| 亚洲视频免费看| 亚洲愉拍自拍另类高清精品| 国产精品男gay被猛男狂揉视频| 中文精品视频一区二区在线观看| 一区二区欧美在线|