正則表達式總結

正則表達式總結


轉載地址:http://www.cnblogs.com/14lcj/archive/2012/08/01/2619124.html

第一點:--------------有關正則前沿介紹 正則表達式是用來進行文本處理的技術,是語言無關的,在幾乎所有語言中都有實現。javascript中還會用到。一個正則表達式就是由普通字符以及特殊字符(稱爲元字符)組成的文字模式。該模式描述在查找文字主體時待匹配的一個或多個字符串。正則表達式作爲一個模板,將某個字符模式與所搜索的字符串進行匹配。就像通配符“*.jpg”、“%ab%”,它是對字符串進行匹配的特殊字符串正則表達式是非常複雜的,不要希望一次都掌握,理解正則表達式能做什麼(字符串的匹配、字符串的提取、字符串的替換),掌握常用的正則表達式用法,以後用到再查就行。

第二點:--------------有關正則使用地方 項目中的採集器、敏感詞過濾、URLRewite、Validator也會涉及到正則表達式。

第三點:--------------元字符介紹 要想學會正則表達式,理解元字符是一個必須攻克的難關。不用刻意記

      1).:匹配任何單個字符。例如正則表達式“b.g”能匹配如下字符串:“big”、“bug”、“b g”,但是不匹配“buug”,“b..g”可以匹配“buug”。 

      2)[ ] :匹配括號中的任何一個字符。例如正則表達式“b[aui]g”匹配bug、big和bag,但是不匹配beg、baug。可以在括號中使用連字符“-”來指定字符的區間來簡化表示,例如正則表達式[0-9]可以匹配任何數字字符,這樣正則表達式“a[0-9]c”等價於“a[0123456789]c”就可以匹配“a0c”、“a1c”、“a2c”等字符串;還可以制定多個區間,例如“[A-Za-z]”可以匹配任何大小寫字母,“[A-Za-z0-9]”可以匹配任何的大小寫字母或者數字。

     3)( ) :將 () 之間括起來的表達式定義爲“組”(group),並且將匹配這個表達式的字符保存到一個臨時區域,這個元字符在字符串提取的時候非常有用。把一些字符表示爲一個整體。改變優先級、定義提取組兩個作用。

     4)| :將兩個匹配條件進行邏輯“或”運算。'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 則匹配 "zood" 或 "food"。

     5)+ :匹配前面的子表達式一次或多次,和*對比(0到多次)。例如正則表達式9+匹配9、99、999等。 “zo+”能匹配 “zo”以及 “zoo” ,不能匹配"z"。

     6)*:匹配0至多個在它之前的子表達式,和通配符*沒關係。例如正則表達式“zo*”能匹配 “z” 、“zo”以及 “zoo”;因此“.*”意味着能夠匹配任意字符串。"z(b|c)*"→zb、zbc、zcb、zccc、zbbbccc。"z(ab)*"能匹配z、zab、zabab(用括號改變優先級)。

     7)? :匹配前面的子表達式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 。一般用來匹配“可選部分”。

     8){n} :匹配確定的 n 次。"zo{2}"→zoo。例如,“e{2}” 不能匹配“bed”中的“e”,但是能匹配“seed”中的兩個“e”。

     9){n,} :至少匹配n次。例如,“e{2,}”不能匹配“bed”中的“e”,但能匹配 “seeeeeeeed”中的所有“e”。

   10){n,m} :最少匹配 n 次且最多匹配 m 次。“e{1,3}”將匹配“seeeeeeeed”中的前三個“e”。

   11)^(shift+6) :匹配一行的開始。例如正則表達式“^regex”能夠匹配字符串“regex我會用”的開始,但是不能匹配“我會用regex”。

   12)^另外一種意思:非!(暫時不用理解)

   13)$ :匹配行結束符。例如正則表達式“浮雲$” 能夠匹配字符串“一切都是浮雲”的末尾,但是不能匹配字符串“浮雲呀”

第三點:-------------簡寫正則表達式 注意這些簡寫表達式是不考慮轉義符的,這裏的\就表示字符\,而不是C#字符串級別的\,在C#代碼中需要使用@或者\雙重轉義。

區分C#級別的轉移和正則表達式級別的轉移,恰好C#的轉義符和正則表達式的轉義符都是\而已。正則表達式的轉移是在C#之後的(層層盤剝)。

把C#的轉義符想成%就明白了。在C#看來@"\-"就是\-這個普通的字符串,只不過在正則表達式分析引擎看來他有了特殊含義。

"\\d"或者@"\d" \d:代表一個數字,等同於[0-9]

\D:代表非數字,等同於[^0-9]

\s:代表換行符、Tab製表符等空白字符

\S:代表非空白字符

\w:匹配字母或數字或下劃線或漢字,即能組成單詞的字符

\W:非\w ,等同於[^\w] d:digital;s:space、w:word。

大寫就是“非”

第四點:-------------.NET中的正則表達式 正則表達式在.Net就是用字符串表示,這個字符串格式比較特殊,無論多麼特殊,在C#語言看來都是普通的字符串,具體什麼含義由Regex類內部進行語法分析。

正則表達式(Regular Expression)的主要類:Regex.IsMatch方法用於判斷一個字符串是否匹配正則表達式。 字符串匹配例子: Regex.IsMatch("bbbbg","^b.*g $"); Regex.IsMatch("bg", "^b.*g $ "); Regex.IsMatch("gege", "^b.*g $ "); 一定不能忘了^和$,否則也能匹配yesbagit 案例1:判斷是否是合法的郵政編碼(6位數字) Regex.IsMatch("100830","^[0-9]{6}$") Regex.IsMatch("119", @"^\d{6}$"); 解釋:由元字符定義得知"[0-9]"表示0到9的任意字符,"{6}"表示前面的字符匹配6此,因此“[0-9]{6}”中的{6}表示對數字匹配6次(000000123)。簡寫表達式得知“[0-9]”可以被“\d”代替,所以第二種寫法“\d{6}”也是正確的。 案例2:判斷一個字符串是不是身份證號碼,即是否是15或18位數字。 錯誤寫法:Regex.IsMatch("123456789123456789", @"^\d{15}|\d{18}$"),表示15位數字開頭或者18位數字結尾 正確寫法:Console.WriteLine(Regex.IsMatch("0111111111111111", @"^\d{15}$|^\d{18}$"))或者@"^(\d{15}|\d{18})$" 案例3:判斷字符串是否爲正確的國內電話號碼,不考慮分機。 比如“010-95555”、“01095555”、“95555”都是正確的號碼。區號爲3位或者4位。 Regex.IsMatch("123456-95555", @"^\d{3,4}\-?\d+$") "^\d{3,4}\-?\d+$"表示被匹配的字符序列應該是由三至四位數字組成,由於長途區號的連字符“-”可有可無,所以這裏使用“?”元字符進行說明。由於連字符“-”在正則表達式 中有特殊含義(表示範圍,比如[0-9]),所以要對其進行轉義。 案例4:判斷一個字符串是否是合法的Email地址。 一個Email地址的特徵就是以一個字符序列開始,後邊跟着“@”符號,後邊又是一個字符序列,後邊跟着符號“.”,最後是字符序列 Regex.IsMatch("[email protected]", @"^\w+@\w+\.\w+$"); []括號中的任意字符,\w字母、數字、下劃線,+一到多個。由於.在正則表達式中有特殊的含義,因此對於真正想表達“.”則需要轉移“\.”。 案例5: 1、匹配IP地址,4段用.分割的最多三位數字。 192.168.54.77、333.333.333.333假設都是正確的。 @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"。.是正則表達式中的特殊含義,因此需要轉義。 2、判斷是否是合法的日期格式“2008-08-08”。四位數字-兩位數字-兩位數字。進一步嚴謹@"^\d{4}\-\d{2}\-\d{2}$" 3、判斷是否是合法的url地址,http://www.test.com/a.htm、ftp://127.0.0.1/1.txt。字符串序列://字符串序列。@"^\w+://.+$"。//簡化的識別,項目中你搜“w3c URL 正則表達式”。.+而不是\w,否則"?id=1"中的?就不能匹配了。 http://www.test.com/a.aspx?id=1

第五點:---------------字符串的提取 正則表達式還可以用來進行字符串提取 Match match = Regex.Match("age=30", @"^(. +)=(.+)$"); if (match.Success) { Console.WriteLine(match.Groups[1] .Value); Console.WriteLine(match.Groups[2] .Value); } match的Success屬性表示是否匹配成功;

正則表達式中用()將要提取的內容括起來,然後就可以通過Match的Groups屬性來得到所有的提取元素,注意Groups的序號是從1開始的,0 有特殊含義 案例:

1)從文件路徑中提取出文件名(包含後綴) @"^.+/(.+)$"。比如從c:/a/b.txt中提取出b.txt這個文件名出來。

項目中用Path.GetFileName更好。

貪婪模式。

2)從“June 26, 1951”中提取出月份June來。@"([a-zA-Z]+)\s+\d{1,2},\s*\d{4}"進行匹配。月份和日之間是必須要有空格分割的,所以使用空白符號“\s”匹配所有的空白字符,此處的空格是必須有的,所以使用“+”標識爲匹配1至多個空格。之後的“,”與年份之間的空格是可有可無的,所以使用“*”表示爲匹配0至多個

3)從Email中提取出用戶名和域名,比如從[email protected]中提取出test和163.com。 4)“192.168.10.5[port=21,type=ftp]”,這個字符串表示IP地址爲192.168.10.5的服務器的21端口提供的是ftp服務,其中如果“,type=ftp”部分被省略,則默認爲http服務。請用程序解析此字符串,然後打印出“IP地址爲***的服務器的***端口提供的服務爲***” ^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\[port=(\d{1,5})(,type=(\w+))?\]$

第六點:---------------貪婪和非貪婪模式 從文本提取出名字: Match match = Regex.Match("大家好。我是S.H.E。我22歲了。我病了,嗚嗚。fffff", "我是(.+)。");//沒有加^$。

看結果。+、*的匹配默認是貪婪(greedy)的:儘可能多的匹配,直到“再貪婪一點兒”其後的匹配模式就沒法匹配爲止。 在+、*後添加?就變成非貪婪模式

(? 的另外一個用途):讓其後的匹配模式儘早的匹配。修改成"我是(.+?)。" 一般開發的時候不用刻意去修飾爲非貪婪模式,只有遇到bug的時候發現是貪婪模式的問題再去解決。

第七點:--------------匹配組 正則表達式可以從一段文本中將所有符合匹配的內容都輸出出來。Match獲得的是匹配的第一個。 Regex.Matches方法可以獲得所有的匹配項。

注意區別:匹配和group的區別: 練習:從一段文本中提取所有的數字 MatchCollection matches = Regex.Matches("大家好,我是Hebe,我22歲了,身高180,我們團隊有3個女女!", @"\d+");

案例:從字符串中提取所有人名 MatchCollection matchs = Regex.Matches(“大家好。我們是S.H.E。我是S。我是H。嗚嗚。fffff", @"我是(.+?)。")

案例:從一個頁面提取所有Email地址,用WebClient,自己動手寫Email羣發器。 練習:從網站抓取所有的圖片地址,下載到硬盤:MatchCollection matches = Regex.Matches(content, "border=0\\s*src=\"(.*?)\">"); 練習:抓取所有超鏈接,特徵:href="地址“ //MatchCollection matches = Regex.Matches(text, "<a\s*href="(.+?)"\s*"); 練習:抓取新聞 採集工具 //MatchCollection //MatchCollection matchs = Regex.Matches(“大家好。我們是S.H.E。我是S。我是H。嗚嗚。fffff", @"我是(.+?)。"); //foreach (Match match in matchs) //{ // if (match.Success) // { // Console.WriteLine(match.Groups[1].Value); // } //}

發佈了1 篇原創文章 · 獲贊 31 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章