asp.net c# 學用的Regex

來源:互聯網
上載者:User

asp教程.net c# 學用的Regex
一、組的分類
正則中的組有擷取的群組和非擷取的群組,而擷取的群組又分為普通的擷取的群組和命名擷取的群組,分別為
擷取的群組:(exp)   
命名擷取的群組:(? <name> exp)   
非擷取的群組:(?:exp) 
 
二、組的作用
1、擷取的群組的作用
 
擷取的群組的作用是將Regexexp匹配到的內容儲存到組裡,供以後使用
 
比如這樣一個字串:
<a href="http://anmo./" title="床上等你"> csdn </a>
我想得到網址,而它符合的規則是在 <a...> 標籤內,那就可以這樣做

c# code
string test = "<a href="http://anmo./" title="床上等你">csdn</a>";
match m = regex.match(test, @"<as*href=""([^""]*)""[^>]*>", regexoptions.ignorecase);
if (m.success)
    messagebox.show(m.groups教程[1].value);

上面的Regex匹配到了 <a href="http://anmo./" title="床上等你"> ,而我們想得到網址,運算式其它部分只是為了保證取到的網址是在 <a...> 標籤內的,所以這裡用到的擷取的群組,把匹配到的網址儲存到擷取的群組裡,然後用m.groups[1].value得到這個擷取的群組所匹配到的內容
m.groups[1].value是一種對捕獲的引用方式,還有另外一種引用方式m.result("$1"),效果是一樣的
 
普通擷取的群組是用1,2,3...這樣的自然數對擷取的群組進行引用的
而命名擷取的群組可以不用去數擷取的群組的序號,直接通過擷取的群組的命稱對它進行引用
 

c# code
string test = "<a href="http://anmo./" title="床上等你">csdn</a>";
match m = regex.match(test, @"<as*href=""(?<url>[^""]*)""[^>]*>", regexoptions.ignorecase);
if (m.success)
    messagebox.show(m.groups["url"].value);

 
至於擷取的群組的分組命名及序號定序,在後面說明
 
2、非擷取的群組的作用
非擷取的群組的作用有兩個,第一個比較常用,第二個瞭解一下即可
 
(1)、節省系統資源,提高效率
在使用“ ¦”表示“或”的關係時,稍微複雜的情況,需要用()來限制“ ¦”的作用範圍,否則即表示“ ¦”的左右兩側整體為“或”的關係,這是題外話,這裡不詳細說明了,還有用{num}來運算式匹配次數時,有時前面也要用到()限制作用範圍
而使用()來限制作用範圍的同時,預設情況下會把匹配到的結果儲存到一個擷取的群組裡,而大多數時候,我們是不需要儲存這部分內容的,這就帶來一定的副作用,浪費了系統資源,降低了效率
非擷取的群組的一個作用就是用來消除這種副作用的,(?:exp)用來匹配exp所表示的規則,但不將匹配結果儲存到擷取的群組裡
 
比如匹配hh:mm:ss這樣的時間

c# code
messagebox.show(regex.ismatch("18:23:55", "^(?:[01][0-9]|2[0-3])(?::[0-5][0-9]){2}$").tostring());

(?:[01][0-9] ¦2[0-3])驗證小時部分是否符合規則,但不會將匹配結果儲存到擷取的群組裡
(?::[0-5][0-9]){2}驗證了分秒部分,但不會將匹配結果儲存到擷取的群組裡
 
(2)、在使用regex.split方法時,起到與regexoptions .explicitcapture參數相同的作用,這個用得不多,瞭解一下就行了
 
三、擷取的群組分組命名及序號排序
普通擷取的群組是按“(”從左至右出現的先後順序以自然數1,2,3...進行命名的
命名擷取的群組就是以(? <name> exp)中的name進行命名的
 
但是要注意一點,在運算式匹配成功的前提下,$0在任何情況下都表示整個運算式所匹配到的內容,m.groups[0].value表示整個運算式匹配到的內容,可以簡寫為m.value
 
另外就是命名擷取的群組除了可以用name對它進行引用外,還可以通過序號對它引用,它的命名規則為:先對普通擷取的群組從左至右進行序號命名,然後再從開頭,從左至右對命名擷取的群組進行序號命名,舉例如下
 
<as*href="(? <url> [^"]*)"s*title="([^"]*)"[^> ]*> (? <text> [ss]*?) </a>
             2   url                  1               3    text
 

c# code
string test = "<a href="http://anmo./" title="床上等你">csdn</a>";
match m = regex.match(test, @"<as*href=""(?<url>[^""]*)""s*title=""([^""]*)""[^>]*>(?<text>[ss]*?)</a>", regexoptions.ignorecase);
if (m.success)
{
    richtextbox1.text += m.groups[0].value + "n";       //<a href="http://anmo./" title="床上等你">csdn</a>
    richtextbox1.text += m.groups[1].value + "n";       //床上等你
    richtextbox1.text += m.groups[2].value + "n";       //http://anmo.
    richtextbox1.text += m.groups["url"].value + "n";   //http://anmo.
    richtextbox1.text += m.groups[3].value + "n";       //csdn
    richtextbox1.text += m.groups["text"].value + "n";  //csdn
}

 
四、組的另一種引用方式
除了上面 m.groups[1].value 和 m.result("$1") 這兩種對結果集進行處理時的引用方式外,還有在替換時的一種引用方式,舉例如下
 
只保留網址和連結文字,去掉 <a...> 標籤中其它無用資訊

c# code
string test = "<a href="http://anmo./" title="床上等你">csdn</a>";
string result = regex.replace(test, @"<as*href=""([^""]*)""s*title=""([^""]*)""[^>]*>(?<text>[ss]*?)</a>", @"<a href=""$1"">${text}</a>", regexoptions.ignorecase);
messagebox.show(result);

 
普通擷取的群組就是用$number來引用,而命名捕獲是用${name}來引用


預搜尋
(?=exp)      
(?!exp)      
(? <=exp)     
(? <!exp)    
 
下面的說明很容易讓人頭暈,不看也罷,我將以另一種方式對它們的作用和用法進行說明
(?=exp)   匹配exp前面的位置   
(?  <=exp)   匹配exp後面的位置   
(?!exp)   匹配後面跟的不是exp的位置   
(?  <!exp)   匹配前面不是exp的位置   
 
有的資料上翻譯為零寬度斷言,我習慣於預搜尋這種叫法,前兩個為正向預搜尋,後兩個為反向預搜尋,當然還有其它翻譯,其實都是一個意思,知道就行,不必在意
 
這四種運算式,它們與非捕獲的相同之處在於,並不將匹配到的結果儲存到擷取的群組,不同之處在於,非擷取的群組匹配到的內容,雖然不儲存到擷取的群組,但卻是在結果$0實實在在存在的,而以上四種運算式所匹配到的內容,一般來說,是不存在$0內的,所以說它們匹配的結果是零寬度的
 
更好的理解方式,是把它們作為附加條件,而不是Regex的組成部分
 
為了更好的說明,先說一下“縫隙”的概念,“縫隙”是零寬度的,它只是字串中的一個位置,而不是實際的字元,如字串“ab”,在“a”前面,“a”和“b”中間,還有“b”後面,分別有一個“縫隙”,也就是整個字串有三個“縫隙”
 
(?=exp)    在所在“縫隙”的後面附加一個條件,也就是“縫隙”後面必須能夠匹配exp的內容  
(?!exp)    在所在“縫隙”的後面附加一個條件,也就是“縫隙”後面必須不能夠匹配exp的內容  
(? <=exp)   在所在“縫隙”的前面附加一個條件,也就是“縫隙”前面必須能夠匹配exp的內容  
(? <!exp)   在所在“縫隙”的前面附加一個條件,也就是“縫隙”前面必須不能夠匹配exp的內容 
 
舉例說明如下:
<[^> ]*> 運算式任意html標籤

附加一個條件
<(?!img)[^> ]*>
這個就表示除 <img...> 標籤外的所有標籤,看下實際例子


c# code
string test = "<p><a href="http://anmo./" title="床上等你"><img src="yun_qi_img/logo.jpg/%22%3ecsdn%3c/a%3e%3c/p>";
matchcollection mc = regex.matches(test, @"<(?!img)[^>]*>", regexoptions .ignorecase);
foreach(match m in mc)
{
    richtextbox1.text += m.value + "n";
}

輸出結果為:
<p>
<a href="http://www.111cn.net/" >
</a>
</p>

這時再看一下 <(?!img)[^> ]*> 這個Regex
(?!img)所在的“縫隙”是“ <”和它後面的第一個字元之間的“縫隙”,它表示的意思就是,在這個“縫隙”的後面,不能是img,整個運算式的意思也就是不匹配 <img...> 標籤

同理, <(?=img)[^> ]*> 表示只匹配 <img...> 標籤

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.