麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > Regex > 正文

正則表達式高級學習技巧

2020-03-16 21:20:52
字體:
來源:轉載
供稿:網友

什么是RE?

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

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

接下來,就讓我們來體驗一些例子吧。

一些簡單的例子

假設要查找文章中Elvis后接有alive的文字符串的話,使用RE可能會經過下列的過程,括號是所下RE的意思:

1.elvis(查找elvis)

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

2./belvis/b(將elvis視為一整體的字查找,如elvis、Elvis乎略字符大小寫時)

“/b”在RE中有特別的意思,在上述的例子中所指的就是字的邊界,所以/belvis/b用/b把elvis的前后邊界界定出來,也就是要elvis這個字。

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

3./belvis/b.*/balive/b(查找elvis后面接有alive的文字符串,如elvisisalive)

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

再看看另外的例子

組成有效的電話號碼

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

4./b/d/d/d-/d/d/d/d(查找七位數字之電話號碼,如123-1234)

每一個/d代表一個數字。”-”則是一般的連字符號,為避免太多重復的/d,RE可以改寫成如5的方式。

5./b/d{3}-/d{4}(查找七位數字電話號碼較好的方法,如123-1234)

在/d后的{3},代表重復前一個項目三次,也就是相等于/d/d/d。

RE的學習及測試工具Expresso

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

.NET中RE的基礎概念

特殊字符

有些字符有特別的意義,比如之前所看到的”/b”、”.”、”*”、”/d”等。”/s”所代表的是任意空格符,比如說spaces、tabs、newlines等.。”/w”代表是任意字母或數字字符。

再看一些例子吧

6./ba/w*/b(查找a開頭的字,如able)

這RE描述要查找一個字的開始邊界(/b),再來是字母”a”,再加任意數目的字母數字(/w*),再接結束這個字的結束邊界(/b)。

7./d+(查找數字字符串)

“+”和”*”非常相似,除了+至少要重復前面的項目一次。也就是說至少有一個數字。

8./b/w{6}/b(查找六個字母數字的字,如ab123c)

下表為RE常用的特殊字符

.除了換行字符的任意字符

/w任意字母數字字符

/s任意空格符

/d任意數字字符

/b界定字的邊界

^文章的開頭,如”^The''用以表示出現于文章開頭的字符串為”The”

$文章的結尾,如”End$”用以表示出現在文章的結尾為”End”

特殊字符”^”及”$”是用來查找某些字必需是文章的開頭或結尾,這在驗證輸入是否符合某一樣式時特別用有,比如說要驗證七位數字的電話號碼,可能會輸入如下9的RE。

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

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

轉意字符(Escapedcharacters)

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

重復前述項目

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

*重復任意次數

+重復至少一次

?重復零次或一次

{n}重復n次

{n,m}重復至少n次,但不超過m次

{n,}重復至少n次

再來試一些例子吧

10./b/w{5,6}/b(查找五個或六個字母數字字符的字,如as25d、d58sdf等)

11./b/d{3}/s/d{3}-/d{4}(查找十個數字的電話號碼,如800123-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]”,所指的就是任意小寫字母或任意數字。

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

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

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

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

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

/W不是字母數字的任意字符

/S不是空格符的任意字符

/D不是數字字符的任意字符

/B不在字邊界的位置

[^x]不是x的任意字符

[^aeiou]不是a、e、i、o、u的任意字符

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

擇一(Alternatives)

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

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

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

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

群組(Grouping)

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

18.(/d{1,3}/.){3}/d{1,3}(尋找網絡地址的簡單RE)

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

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

19.((2[0-4]/d|25[0-5]|[01]?/d/d?)/.){3}(2[0-4]/d|25[0-5]|[01]?/d/d?)(尋找網絡地址)

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

ExpressoAnalyzerView

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

當次描述用括號群組起來時,符合次描述的文字可用在之后的程序處理或RE本身。在預設的情型下,所符合的群組是由數字命名,由1開始,由順序是由左至右,這自動群組命名,可在Expresso中的skeletonview或resultview中看到。

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

20./b(/w+)/b/s*/1/b(尋找重復字,此處說的重復是指同樣的字,中間有空白隔開如dogdog這樣的字)

(/w+)會抓取至少一個字符的字母或數字的字,并將它命名為群組1,之后是查找任意空格符,再接和群組1相同的文字。

如果不喜歡群組自動命名的1,也可以自行命名,以上述例子為例,(/w+)改寫為(?/w+),這就是將所抓取的群組命名為Word,Backreference就要改寫成為/k

21./b(?/w+)/b/s*/k/b(使用自行命名群組抓取重復字)

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

抓取(Captures)

(exp)符合exp并抓取它進自動命名的群組

(?exp)符合exp并抓取它進命名的群組name

(?:exp)符合exp,不抓取它

Lookarounds

(?=exp)符合字尾為exp的文字

(?<=exp)符合前綴為exp的文字

(?!exp)符合后面沒接exp字尾的文字

(?

批注Comment

(?#comment)批注

PositiveLookaround

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

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

22./b/w+(?=ing/b)(字尾為ing的字,比如說filling所符合的就是fill)

(?<=exp)是一個”zero-widthpositivelookbehindassertion”。它指的就是符合前綴為exp的文字,但不包含exp本身。

23.(?<=/bre)/w+/b(前綴為re的字,比如說repeated所符合的就是peated)

24.(?<=/d)/d{3}/b(在字尾的三位數字,且之前接一位數字)

25.(?<=/s)/w+(?=/s)(由空格符分隔開的字母數字字符串)

NegativeLookaround

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

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

這樣的RE會有一個問題,因為[^u]要對應一個字符,所以若q是字的最后一個字母,[^u]這樣的下法就會將空格符對應下去,結果就有可能會符合二個字,比如說”Iraqhaha”這樣的文字。使用NegativeLookaround就能解決這樣的問題。

27./b/w*q(?!u)/w*/b(一個字,其字母里有q但接下來的字母不是u)

這是”zero-widthnegativelookaheadassertion”。

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

同樣的,可以使用(?

29.(?

30.(?<=<(/w+)>.*(?=<///1>(HTML卷標間的文字)

這使用lookahead及lookbehindassertion來取出HTML間的文字,不包括HTML卷標。

請批注(CommentsPlease)

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

31.HTML卷標間的文字,加上批注

(?<= #查找前綴,但不包含它

<(/w+)>#HTML標簽

)#結束查找前綴

.*#符合任何文字

(?=#查找字尾,但不包含它

<///1>#符合所抓取群組1之字符串,也就是前面小括號的HTML標簽

)#結束查找字尾

尋找最多字符的字及最少字符的字(GreedyandLazy)

當RE下要查找一個范圍的重復時(如”.*”),它通常會尋找最多字符的符合字,也就是Greedymatching。舉例來說。

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

若有一字符串是”aabab”,使用上述RE所得到的符合字符串就是”aabab”,因為這是尋找最多字符的字。有時希望是符合最少字符的字也就是lazymatching。只要將重復前述項目的表加上問號(?)就可以把它們全部變成lazymatching。因此”*?”代表的就是重復任意次數,但是使用最少重復的次數來符合。舉個例子來說:

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

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

*?重復任意次數,最少重復次數為原則

+?重復至少一次,最少重復次數為原則

??重復零次或一次,最少重復次數為原則

{n,m}?重復至少n次,但不超過m次,最少重復次數為原則

{n,}?重復至少n次,最少重復次數為原則

還有什么沒提到呢?

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

#語法說明

/aBell字符

/b通常是指字的邊界,在字符組里所代表的就是backspace

/tTab

34/rCarriagereturn

/vVerticalTab

/fFromfeed

35/nNewline

/eEscape

36/nnnASCII八位碼為nnn的字符

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

38/unnnnUnicode為nnnn的字符

39/cNControlN字符,舉例來說Ctrl-M是/cM

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

41/Z字符串的結尾

/z字符串的結尾

42/G目前查找的開始

43/p{name}Unicode字符組名稱為name的字符,比如說/p{Lowercase_Letter}所指的就是小寫字

(?>exp)Greedy次描述,又稱之為non-backtracking次描述。這只符合一次且不采backtracking。

44(?-exp)

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

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

46(?im-nsx)為之后的群組更改RE選項。

(?(exp)yes|no)次描述exp視為zero-widthpositivelookahead。若此時有符合,則yes次描述為下一個符合標的,若否,則no次描述為下一個符合標的。

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

(?(name)yes|no)若name群組為有效群組名稱,則yes次描述為下一個符合標的,若否,則no次描述為下一個符合標的。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产乱淫av片免费 | 国产午夜精品一区二区三区在线观看 | 天天黄色片| 狠狠干精品视频 | 黄色网址免费进入 | 97中文| 久久综合综合 | 精品成人免费视频 | h视频免费在线 | 成人一区二区在线观看视频 | 姑娘第5集高清在线观看 | 黄色片免费在线 | 成人一级片毛片 | 爱逼av| 久久中出 | 成人性生活视频在线播放 | av影院在线播放 | 日日操夜夜透 | 一级成人欧美一区在线观看 | fc2国产成人免费视频 | 久草视频福利在线观看 | 91专区在线观看 | 99精彩视频在线观看 | 亚洲第一综合 | 成人福利网 | 欧产日产国产精品99 | 免费黄色在线电影 | 亚洲网站免费观看 | 91热久久免费频精品黑人99 | 91成人在线免费 | 国产精品久久久久久久亚洲按摩 | 曰本三级日本三级日本三级 | 深夜福利视频免费观看 | 国产盼盼私拍福利视频99 | 欧产日产国产精品乱噜噜 | 日韩视频在线视频 | 欧美成人精品一区 | 欧美精品免费一区二区三区 | 成码无人av片在线观看网站 | 特黄一区二区三区 | 精品视频 久久久 |