欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          正則表達(dá)式高級學(xué)習(xí)技巧

          什么是RE?
          想必各位大大在做文件查找的時侯都有使用過萬用字符”*”,比如說想查找在Windows目錄下所有的Word文件時,你可能就會用”*.doc”這樣的方式來做查找,因為”*”所代表的是任意的字符。RE所做的就是類似這樣的功能,但其功能更為強大。

          寫程序時,常需要比對字符串是否符合特定樣式,RE最主要的功能就是來描述這特定的樣式,因此可以將RE視為特定樣式的描述式,舉個例子來說,”w+”所代表的就是任何字母與數(shù)字所組成的非空字符串(non-null?string)。在.NET?framework中提供了非常強大的類別庫,藉此可以很輕易的使用RE來做文字的查找與取代、對復(fù)雜標(biāo)頭的譯碼及驗證文字等工作。
          接下來,就讓我們來體驗一些例子吧。

          一些簡單的例子
          假設(shè)要查找文章中Elvis后接有alive的文字符串的話,使用RE可能會經(jīng)過下列的過程,括號是所下RE的意思:

          1.?elvis?(查找elvis)

          上述代表所要查找的字符順序為elvis。在.NET中可以設(shè)定乎略字符的大小寫,所以”Elvis”、”ELVIS”或者是”eLvIs”都是符合1所下的RE。但因為這只管字符出現(xiàn)的順序為elvis,所以pelvis也是符合1所下的RE??梢杂?的RE來改進(jìn)。

          2.?belvisb?(將elvis視為一整體的字查找,如elvis、Elvis乎略字符大小寫時)
          “b”在RE中有特別的意思,在上述的例子中所指的就是字的邊界,所以belvisb用b把elvis的前后邊界界定出來,也就是要elvis這個字。

          假設(shè)要將同一行里elvis后接有alive的文字符串找出來,此時就會用到另外二個特別意義的字符”.”及”*”。”.”所代表就是除了換行字符的任意字符,而”*”所代表的是重復(fù)*之前項目直到找到符合RE的字符串。所以”.*”所指的就是除了換行字符外的任意數(shù)目的字符數(shù)。所以查找同一行里elvis后接有alive的文字符串找出來,則可下如3之RE。

          3.?belvisb.*baliveb?(查找elvis后面接有alive的文字符串,如elvis?is?alive)

          用簡單之特別字符就可以組成功能強大的RE,但也發(fā)現(xiàn)當(dāng)使用越來越多的特別字符時,RE就會越來越難看得懂了。

          再看看另外的例子
          組成有效的電話號碼

          假使要從網(wǎng)頁上收集顧客格式為xxx-xxxx的7位數(shù)字的電話號碼,其中x是數(shù)字,RE可能會這樣寫。

          4.?bddd-dddd?(查找七位數(shù)字之電話號碼,如123-1234)
          每一個d代表一個數(shù)字。”-”則是一般的連字符號,為避免太多重復(fù)的d,RE可以改寫成如5的方式。

          5.?bd{3}-d{4}?(查找七位數(shù)字電話號碼較好的方法,如123-1234)
          在d后的{3},代表重復(fù)前一個項目三次,也就是相等于ddd。

          RE的學(xué)習(xí)及測試工具?Expresso

          因為RE不易閱讀及使用者容易會下錯RE的特性,Jim大大開發(fā)了一個工具軟件Expresso,用來幫助使用者學(xué)習(xí)及測試RE,除了上面所述的網(wǎng)址之外,也可以上Ultrapico網(wǎng)站。安裝完expresso后,在expression%20%20library中,jim大大把文章的例子都建立在其中,可以邊看文章邊測試,也可以試著修改范例所下的re,馬上可以看到結(jié)果,小弟覺得非常好用。各位大大可以試試。/”。安裝完Expresso后,在Expression?Library中,Jim大大把文章的例子都建立在其中,可以邊看文章邊測試,也可以試著修改范例所下的RE,馬上可以看到結(jié)果,小弟覺得非常好用。各位大大可以試試。

          .NET中RE的基礎(chǔ)概念
          特殊字符

          有些字符有特別的意義,比如之前所看到的”b”、”.”、”*”、”d”等?!眘”所代表的是任意空格符,比如說spaces、tabs、newlines等.?!眞”代表是任意字母或數(shù)字字符。

          再看一些例子吧
          6.?baw*b?(查找a開頭的字,如able)
          這RE描述要查找一個字的開始邊界(b),再來是字母”a”,再加任意數(shù)目的字母數(shù)字(w*),再接結(jié)束這個字的結(jié)束邊界(b)。

          7.?d+?(查找數(shù)字字符串)
          “+”和”*”非常相似,除了+至少要重復(fù)前面的項目一次。也就是說至少有一個數(shù)字。

          8.?bw{6}b?(查找六個字母數(shù)字的字,如ab123c)

          下表為RE常用的特殊字符

          .?除了換行字符的任意字符
          w?任意字母數(shù)字字符
          s?任意空格符
          d?任意數(shù)字字符
          b?界定字的邊界
          ^?文章的開頭,如”^The”?用以表示出現(xiàn)于文章開頭的字符串為”The”
          $?文章的結(jié)尾,如”End$”用以表示出現(xiàn)在文章的結(jié)尾為”End”
          特殊字符”^”及”$”是用來查找某些字必需是文章的開頭或結(jié)尾,這在驗證輸入是否符合某一樣式時特別用有,比如說要驗證七位數(shù)字的電話號碼,可能會輸入如下9的RE。

          9.?^d{3}-d{4}$?(驗證七位數(shù)字之電話號碼)

          這和第5個RE相同,但其前后都無其它的字符,也就是整串字符串只有這七個數(shù)字的電話號碼。在.NET中如果設(shè)定Multiline這個選項,則”^”和”$”會每行進(jìn)行比較,只要某行的開頭結(jié)尾符合RE即可,而不是整個文章字符串做一次比較。

          轉(zhuǎn)意字符(Escaped?characters)

          有時可能會需要”^”、”$”單純的字面意義(literal?meaning)而不要將它們當(dāng)成特殊字符,此時””字符就是用來移除特殊字符特別意義的字符,因此”^”、”.”、”\”所代表的就是”^”、”.”、””的字面意義。

          重復(fù)前述項目

          在前面看過”{3}”及”*”可以用來重復(fù)前述字符,之后我們會看到如何用同樣的語法重復(fù)整個次描述(subexpressions)。下表是使用重復(fù)前述項目的一些方式。

          *?重復(fù)任意次數(shù)
          +?重復(fù)至少一次
          ??重復(fù)零次或一次
          {n}?重復(fù)n次
          {n,m}?重復(fù)至少n次,但不超過m次
          {n,}?重復(fù)至少n次

          再來試一些例子吧

          10.?bw{5,6}b?(查找五個或六個字母數(shù)字字符的字,如as25d、d58sdf等)
          11.?bd{3}sd{3}-d{4}?(查找十個數(shù)字的電話號碼,如800?123-1234)
          12.?d{3}-d{2}-d{4}?(查找社會保險號碼,如?123-45-6789)
          13.?^w*?(每行或整篇文章的第一個字)
          在Espresso可試試有Multiline和沒Multiline的不同。

          匹配某范圍的字符

          有時需要查找某些特定的字符時怎么辨?這時中括號”[]”就派上了用場。因此[aeiou]所要查找的是”a”、”e”、”i”、”o”、”u”這些元音,[.?!]所要查找的是”.”、”?”、”!”這些符號,在中括號中的特殊字符的特別意義都會被移除,也就是解譯成單純的字面意義。也可以指定某些范圍的字符,如”[a-z0-9]”,所指的就是任意小寫字母或任意數(shù)字。

          接下來再看一個比較初復(fù)雜查找電話號碼的RE例子

          14.?(?d{3}[(?]?s?d{3}[-?]d{4}?(查找十位數(shù)字之電話號碼,如(080)?333-1234?)

          這樣的RE可查找出較多種格式的電話號碼,如(080)?123-4567、511?254?6654等?!??”代表一個或零個左小括號”(“,而”[(?]”代表查找一個右小括號”)”或空格符,”s?”指一個或零個空格符組。但這樣的RE會將類似”800)?45-3321”這樣的電話找出來,也就是括號沒有對稱平衡的問題,之后會學(xué)到擇一(alternatives)來決解這樣的問題。

          不包含在某特定字符組里(Negation)

          有時需要查找在包含在某特定字符組里的字符,下表說明如何做類似這樣的描述。

          W?不是字母數(shù)字的任意字符
          S?不是空格符的任意字符
          D?不是數(shù)字字符的任意字符
          B?不在字邊界的位置
          [^x]?不是x的任意字符
          [^aeiou]?不是a、e、i、o、u的任意字符

          15.?S+?(不包含空格符的字符串)

          擇一(Alternatives)

          有時會需要查找?guī)讉€特定的選擇,此時”|”這個特殊字符就派上用場了,舉例來說,要查找五個數(shù)字及九個數(shù)字(有”-”號)的郵政編碼。

          16.?bd{5}-d{4}b|bd{5}b?(查找五個數(shù)字及九個數(shù)字(有”-”號)的郵政編碼)

          在使用Alternatives時需要注意的是前后的次序,因為RE在Alternatives中會優(yōu)先選擇符合最左邊的項目,16中,如果把查找五個數(shù)字的項目放在前面,則這RE只會找到五個數(shù)字的郵政編碼。了解了擇一,可將14做更好的修正。

          17.?((d{3})|d{3})s?d{3}[-?]d{4}?(十個數(shù)字的電話號碼)

          群組(Grouping)

          括號可以用來介定一個次描述,經(jīng)由次描述的介定,可以針對次描述做重復(fù)或及他的處理。

          18.?(d{1,3}.){3}d{1,3}?(尋找網(wǎng)絡(luò)地址的簡單RE)

          此RE的意思第一個部分(d{1,3}.){3},所指的是,數(shù)字最小一位最多三位,并且后面接有”.”符號,此類型的共有三個,之后再接一到三位的數(shù)字,也就是如192.72.28.1這樣的數(shù)字。

          但這樣會有個缺點,因為網(wǎng)絡(luò)地址數(shù)字最多只到255,但上述的RE只要是一到三位的數(shù)字都是符合的,所以這需要讓比較的數(shù)字小于256才行,但只單獨使用RE并無法做這樣的比較。在19中使用擇一來將地址的限制在所需要的范圍內(nèi),也就是0到255。

          19.?((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)?(尋找網(wǎng)絡(luò)地址)

          有沒有發(fā)覺RE越來越像外星人說的話了?就以簡單的尋找網(wǎng)絡(luò)地址,直接看RE都滿難理解的哩。

          Expresso?Analyzer?View

          Expresso提供了一個功能,它可以將所下的RE變成樹狀的說明,一組組的分開說明,提供了一個好的除錯環(huán)境。其它的功能,如部分符合(Partial?Match只查找反白RE的部分)及除外符合(Exclude?Match只不查找反白RE的部分)就留給各位大大試試。

          當(dāng)次描述用括號群組起來時,符合次描述的文字可用在之后的程序處理或RE本身。在預(yù)設(shè)的情型下,所符合的群組是由數(shù)字命名,由1開始,由順序是由左至右,這自動群組命名,可在Expresso中的skeleton?view或result?view中看到。

          Backreference是用來查找群組中抓取的符合文字所相同的文字。舉例來說”1”所指符合群組1所抓取的文字。

          20.?b(w+)bs*1b?(尋找重復(fù)字,此處說的重復(fù)是指同樣的字,中間有空白隔開如dog?dog這樣的字)
          (w+)會抓取至少一個字符的字母或數(shù)字的字,并將它命名為群組1,之后是查找任意空格符,再接和群組1相同的文字。

          如果不喜歡群組自動命名的1,也可以自行命名,以上述例子為例,(w+)改寫為(?<Word>w+),這就是將所抓取的群組命名為Word,Backreference就要改寫成為k<Word>
          21.?b(?<Word>w+)bs*k<Word>b?(使用自行命名群組抓取重復(fù)字)

          使用括號還有許多特別的語法元素,比較通用的列表如下:

          抓取(Captures)
          (exp)?符合exp并抓取它進(jìn)自動命名的群組
          (?<name>exp)?符合exp并抓取它進(jìn)命名的群組name
          (?:exp)?符合exp,不抓取它
          Lookarounds
          (?=exp)?符合字尾為exp的文字
          (?<=exp)?符合前綴為exp的文字
          (?!exp)?符合后面沒接exp字尾的文字
          (?<!exp)?符合前面沒接exp前綴的文字
          批注Comment
          (?#comment)?批注

          Positive?Lookaround

          接下來要談的是lookahead及l(fā)ookbehind?assertions。它們所查找的是目前符合之前或之后的文字,并不包含目前符合本身。這些就如同”^”及”b”特殊字符,本身并不會對應(yīng)任何文字(用來界定位置),也因此稱做是zero-width?assertions,看些例子也許會清楚些。

          (?=exp)是一個”zero-width?positive?lookahead?assertion”。它指的就是符合字尾為exp的文字,但不包含exp本身。

          22.?bw+(?=ingb)?(字尾為ing的字,比如說filling所符合的就是fill)
          (?<=exp)是一個”zero-width?positive?lookbehind?assertion”。它指的就是符合前綴為exp的文字,但不包含exp本身。

          23.?(?<=bre)w+b?(前綴為re的字,比如說repeated所符合的就是peated)
          24.?(?<=d)d{3}b?(在字尾的三位數(shù)字,且之前接一位數(shù)字)
          25.?(?<=s)w+(?=s)?(由空格符分隔開的字母數(shù)字字符串)

          Negative?Lookaround

          之前有提到,如何查找一個非特定或非在特定群組的字符。但如果只是要驗證某字符不存在而不要對應(yīng)這些字符進(jìn)來呢?舉個例子來說,假設(shè)要查找一個字,它的字母里有q但接下來的字母不是u,可以用下列的RE來做。

          26.?bw*q[^u]w*b?(一個字,其字母里有q但接下來的字母不是u)

          這樣的RE會有一個問題,因為[^u]要對應(yīng)一個字符,所以若q是字的最后一個字母,[^u]這樣的下法就會將空格符對應(yīng)下去,結(jié)果就有可能會符合二個字,比如說”Iraq?haha”這樣的文字。使用Negative?Lookaround就能解決這樣的問題。

          27.?bw*q(?!u)w*b?(一個字,其字母里有q但接下來的字母不是u)
          這是”zero-width?negative?lookahead?assertion”。

          28.?d{3}(?!d)?(三個位的數(shù)字,其后不接一個位數(shù)字)

          同樣的,可以使用(?<!exp),”zero-width?negative?lookbehind?assertion”,來符合前面沒接exp前綴的文字符串。

          29.?(?<![a-z?])w{7}?(七個字母數(shù)字的字符串,其前面沒接字母或空格)

          30.?(?<=<(w+)>.*(?=</1>?(HTML卷標(biāo)間的文字)
          這使用lookahead及l(fā)ookbehind?assertion來取出HTML間的文字,不包括HTML卷標(biāo)。

          請批注(Comments?Please)
          括號還有個特殊的用途就是用來包住批注,語法為”(?#comment)”,若設(shè)定”Ignore?Pattern?Whitespace”選項,則RE中的空格符當(dāng)RE使用時會乎略。此選項設(shè)定時,”#”之后的文字會乎略。

          31.?HTML卷標(biāo)間的文字,加上批注

          (?<=? #查找前綴,但不包含它
          <(w+)>?#HTML標(biāo)簽
          )?#結(jié)束查找前綴
          .*?#符合任何文字
          (?=?#查找字尾,但不包含它
          </1>?#符合所抓取群組1之字符串,也就是前面小括號的HTML標(biāo)簽
          )?#結(jié)束查找字尾

          尋找最多字符的字及最少字符的字(Greedy?and?Lazy)
          當(dāng)RE下要查找一個范圍的重復(fù)時(如”.*”),它通常會尋找最多字符的符合字,也就是Greedy?matching。舉例來說。

          32.?a.*b?(開始為a結(jié)束為b的最多字符的符合字)

          若有一字符串是”aabab”,使用上述RE所得到的符合字符串就是”aabab”,因為這是尋找最多字符的字。有時希望是符合最少字符的字也就是lazy?matching。只要將重復(fù)前述項目的表加上問號(?)就可以把它們?nèi)孔兂蒷azy?matching。因此”*?”代表的就是重復(fù)任意次數(shù),但是使用最少重復(fù)的次數(shù)來符合。舉個例子來說:

          33.?a.*?b?(開始為a結(jié)束為b的最少字符的符合字)

          若有一字符串是”aabab”,使用上述RE第一個所得到的符合字符串就是”aab”再來是”ab”,因為這是尋找最少字符的字。

          *??重復(fù)任意次數(shù),最少重復(fù)次數(shù)為原則
          +??重復(fù)至少一次,最少重復(fù)次數(shù)為原則
          ???重復(fù)零次或一次,最少重復(fù)次數(shù)為原則
          {n,m}??重復(fù)至少n次,但不超過m次,最少重復(fù)次數(shù)為原則
          {n,}??重復(fù)至少n次,最少重復(fù)次數(shù)為原則

          還有什么沒提到呢?

          到目前為止,已經(jīng)提到了許多建立RE的元素,當(dāng)然還有許多元素沒有提到,下表整理了一些沒提到的元素,在最左邊的字段的數(shù)字是說明在Expresso中的例子。

          #?語法?說明

          a?Bell?字符
          b?通常是指字的邊界,在字符組里所代表的就是backspace
          t?Tab

          34?r?Carriage?return

          v?Vertical?Tab
          f?From?feed

          35?n?New?line
          e?Escape

          36?nnn?ASCII八位碼為nnn的字符

          37?xnn?十六位碼為nn的字符

          38?unnnn?Unicode為nnnn的字符

          39?cN?Control?N字符,舉例來說Ctrl-M是cM

          40?A?字符串的開始(和^相似,但不需籍由multiline選項)

          41?Z?字符串的結(jié)尾
          z?字符串的結(jié)尾

          42?G?目前查找的開始

          43?p{name}?Unicode?字符組名稱為name的字符,比如說p{Lowercase_Letter}?所指的就是小寫字
          (?>exp)?Greedy次描述,又稱之為non-backtracking次描述。這只符合一次且不采backtracking。

          44?(?<x>-<y>exp)

          or?(?-<y>exp)?平衡群組。雖復(fù)雜但好用。它讓已命名的抓取群組可以在堆棧中操作使用。(小弟對這個也是不太懂哩)

          45?(?im-nsx:exp)?為次描述exp更改RE選項,比如(?-i:Elvis)就是把Elvis大乎略大小寫的選項關(guān)掉

          46?(?im-nsx)?為之后的群組更改RE選項。
          (?(exp)yes|no)?次描述exp視為zero-width?positive?lookahead。若此時有符合,則yes次描述為下一個符合標(biāo)的,若否,則no?次描述為下一個符合標(biāo)的。
          (?(exp)yes)?和上述相同但無no次描述
          (?(name)yes|no)?若name群組為有效群組名稱,則yes次描述為下一個符合標(biāo)的,若否,則no?次描述為下一個符合標(biāo)的。

          47?(?(name)yes)?和上述相同但無no次描述

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號