簡析正則表達式


前段時間我利用業余時間開發了一套基於標簽的CMS系統,在其中為了處理基於標簽的數據提取與數據填充大量的使用了正則表達式,在這里將我將正則表達式的語法和用法進行簡單的描述,然后下篇中將介紹在c#中利用正則表達式的方法與代碼實例。

什么是正則表達式
基本說來,正則表達式是一種用來描述一定數量文本的模式。Regex代表Regular Express。我們使用一種自定義的模式來匹配一定數量的文本,並從中提取所需數據。如同window的通配符,如:*.txt查找所有txt文件。*就被解釋成任意字符。

一個簡單的正則表達式

作為慣例,我們都是從hello world開始的。那么這里同樣這樣開始。為了匹配hello world這11個字符,正則表達式為:^hello\sworld$。其中^代表開頭的錨點、$代表結束的錨點、\s代表匹配一個空格。一個重要的注意事項,正則表達式是占位的,也就是說,正則表達式中的一個字符一定要對應實際文本中的一個字符。如上面的正則表達式就不能匹配” hello world”,因為” hello….”前面多了一個空格。

另一個正則表達式
如果我們需要匹配一個ipv4的ip地址;總所周知,ip地址分為4段,每段以’.’分割。每段大小在0-255之間。其中前三段都以’.’結尾,最后一段沒有。經過分析得到如下結論。

1) 前三段的匹配模式是相同的,最后一段的匹配模式與前三段只是不以’.’結尾

2) Ipv4的ip地址每段范圍在0-255之間。可以是0-9,可以是10-99,也可以是100-255。其中需要主要的是100-199范圍和200-255范圍,如果首位以1開頭,則后兩位可以是任意數字,如果首位以2開頭,第二位只能是0-5,而且,當第二位是0-4的時候第三位可以是任意數字,當第二位是5的時候第三位只能是0-5

下面我們寫出符合上面第二點的匹配模式

① 當首位是2,且第二位是0-4的時候:2[0-4]\d,

② 當首位是2,且第二位是5的時候:25[0-5]

③ 當首位是0或則1的時候,第二三位可以是任意數字:[01]\d\d

④ 當首位不是0-2的時候,這時該地址就不能是100-255的范圍,只能是0-9或者10-99的范圍,當在0-9范圍的時候,一位任意數字就可以:\d,當在10-99的時候,兩位數字就可以:\d{2};

⑤ 然后觀察第③和第④點可以發現,當首位是0-1而且出現三位的時候應用第③點,當首位不是0-1且不是三位時應有第④點。變可以融合第③④點為:[01]?\d\d?

現在每段0-255范圍的匹配模式已經書寫完成了,然后考慮前三段以’.’結尾的問題,最終獲得匹配模式: ^(2[0-4]\d|25[0-5]|[01]?\d\d?\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$

元字符
通過以上的兩個實例,相信大家已經對正則表達式有了一個初步的理解,現在這里列出正則表達式的元字符,元字符的定義和語言的關鍵字含義類似,都是一些在系統中有特殊含義的字符。

1) ‘.’ :匹配任意字符

2) \w :匹配字母或數字或下划線或漢字

3) \s :匹配空白字符

4) \d :匹配任意數字

5) \b :匹配開頭或則結尾

6) ^ :匹配字符串的開頭

7) $ :匹配字符串的結尾

重復與貪婪重復和惰性重復
重復的含義是指重復匹配滿足某一匹配模式的文本。如例中(匹配ip)的’?’號就是一個重復的例子,它的含義是某一匹配模式,至多出現一次。以下列出一些重復的標示:

1) * :星號,重復任意多次,如:\w*,代表任意字母,數字,下划線,漢字出現任意多次

2) + :加號:至少出現一次,如:\d+,代表任意數字至少出現一次

3) ? :問好:至多出現一次(出現一次或則不出現),如:\s?,代表空白字符出現0或則1次

4) {n}:n代表任意數字,如:.{5},代表任意字符出現5次

5) {n,}:n代表任意數字,如:\d{5,},代表任意數字出現5到多次

6) {n,m}:n,m代表任意數字,如:\d{5,10},代表任意數字出現5到10次

貪婪與惰性匹配

首先看一個正則表達式例子:“<.*>”

這個正則表達式將匹配以’<’開頭,’>’結尾中間任意次任意字符,如:<br/>,<div/>,</script>等。當如果用該正則表達式去匹配<div>hello world</div>的話被匹配出的文本就是<div>hello world</div>,因為默認情況下正則表達式是貪婪匹配。正則表達式引擎或默認情況下將默認搜索最后一個匹配錨點。所以本例中的最后匹配錨點是</div>的>而不是<div>的>。這便是貪婪匹配。

既然明白有貪婪匹配,就必然需知惰性匹配

以上為上面這個正則表達式例子稍作改動:<.*?>,我們在*后面加上一個問號便告訴引擎按照惰性匹配的方式進行搜索,使用這個正則表達式匹配<div>hello world</div>得到的結果會有兩個,一個是<div>另一個是</div>。因為我們沒有限定開頭和結尾。

字符集,分歧,反義

字符集:[A-Za-z0-9],匹配一個字符,這個字符是A-Za-z0-9中的任意一個

分歧:(a|b)*,a或則b出現任意多次

反義:[^ab]+,非a和b出現至少一次

分組
正則表達式的分組以()小括號進行標示,如:(\w*)。標示將\w*划分為一個匹配單元,及分組。<(\w+?)[A-Za-z0-9"=\s]*>.*?</\1>這個正則表達式能夠匹配如:<div class=”box”>hello world</div>段,值得注意的是我們將\w+進行了分組,然后再后面使用\1引用本分組。默認情況下,引擎將至左向右將第一個分組命名為第1組,第二個分組命名為第2組......我們也能顯示的給分組命名,本實例中正則表達式也能寫成:<(?<g1>\w+?)[A-Za-z0-9"=\s]*>.*?</\k<g1>>我們將\w+的分組命名為g1,以后通過\k<name>引用。

 

轉載自 https://www.cnblogs.com/GuoPeng/archive/2011/05/05/2037588.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM