Further Study of Rugular Expresions第1/2頁
來源:互聯網
上載者:User
小弟便興起了學一學re的想法,但小弟天生就比較懶一些,總希望看有沒有些快速學習的方式,於是小弟又請出google大神,藉由祂的神 力,小弟在網路上找到了jim hollenhorst先生的文章,經過了閱讀,小弟覺得真是不錯,所以就做個小心得報告,跟move-to.net的朋 友分享,希望能為各位大大帶來一丁點在學習re時的協助。jim hollenhorst大大文章之網址如下,有需要的大大可直接連結。
the 30 minute regex tutorial by jim hollenhorst
http://www.codeproject.com/useritems/regextutorial.asp
什麼是re?
想必各位大大在做檔案尋找的時侯都有使用過萬用字元”*”,比如說想尋找在windows目錄下所有的word檔案時,你可能就會用”*.doc”這樣的方式來做尋找,因為”*”所代表的是任意的字元。re所做的就是類似這樣的功能,但其功能更為強大。
寫程式時,常需要比對字串是否符合特定樣式,re最主要的功能就是來描述這特定的樣式,因此可以將re視為特定樣式的描述式,舉個例子來說,”\ w +”所代表的就是任何字母與數字所組成的非Null 字元串(non-null string)。在.net framework中提供了非常強大的類別庫, 藉此可以很輕易的使用re來做文字的尋找與取代、對複雜標題的解碼及驗證文字等工作。
學習re最好的方式就是藉由例子親自來做做看。jim hollenhorst大大也提供了一個工具程式expresso(來杯咖啡吧),來協助我們學習re,下載的網址是http://www.codeproject.com/useritems/regextutorial/expressosetup2_1c.zip。
接下來,就讓我們來體驗一些例子吧。
一些簡單的例子
假設要尋找文章中elvis後接有alive的文字串的話,使用re可能會經過下列的過程,括弧是所下re的意思:
1. elvis (尋找elvis)
上述代表所要尋找的字元順序為elvis。在.net中可以設定乎略字元的大小寫,所以”elvis”、”elvis”或者是”elvis”都是符合 1 所下的re。但因為這隻管字元出現的順序為elvis,所以pelvis也是符合1所下的re。可以用2的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的文字串,如elvis is alive)
用簡單之特別字元就可以組成功能強大的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網站(http://www.ultrapico.com)。安裝完expresso後,在expression library中,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即可,而不是整個文章字串做一次比較。
轉意字元(escaped characters)
有時可能會需要”^”、”$”單純的字面意義(literal meaning)而不要將它們當成特殊字元,此時”\”字元就是用來移除特殊字元特別意義的字元,因此”\^”、”\.”、”\\”所代表的就是”^”、”.”、”\”的字面意義。
重複前述項目
在前面看過”{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} (尋找十個數位電話號碼,如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]”,所指的就是任意小寫字母或任一數字。
接下來再看一個比較初複雜尋找電話號碼的re例子
14. \(?\d{3}[( ] \s?\d{3}[- ]\d{4} (尋找十位元字之電話號碼,如(080) 333-1234 )
這樣的re可尋找出較多種格式的電話號碼,如(080) 123-4567、511 254 6654等。”\(?”代表一個或零個左小括弧”(“, 而”[( ]”代表尋找一個右小括弧”)”或空格符,”\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做更好的修正。