本章主要想和大家分享下正則運算式的一些基礎用法,希望能夠對一些小白有所幫助,也為了防止自己以后遺忘相關知識點,下面我們正式進入主題,
一、正則運算式
1、正則運算式是由普通字符(例如字符 a 到 z)以及特殊字符(稱為元字符)組成的文字模式,
2、正則運算式作為一個模板,將某個字符模式與所搜索的字串進行匹配,
3、在撰寫處理字串的程式或網頁時,經常會有查找或替換符合某些復雜規則的字串的需要,
4、正則運算式就是記錄文本規則的代碼,
作用:
1、查找資料
2、替換資料
正則運算式能做什么(字串的匹配、字串的提取、字串的替換)
二、正則運算式的構成
1、普通字符(如果直接寫多個普通字符,則會被當做一個整體的字串來匹配)
這包括所有的大小寫字母字符,所有數字,所有標點符號以及一些特殊符號,
例如:Hello world xyh666
2、定義字符集(取值范圍)(該點都是匹配單個字符,要想匹配字串需要結合限定符來實作)
[a-e] 表示a到e這些字符中的某一個字符
[aeiou] 表示aeiou這5個字符其中的某一個字符
[a-zA-Z] 表示大寫、小寫字母中的某一個字符
[0-9] 表示0到9之間某一個數字
^ 代表非
[^lsjd] :不是中括號中的任意一個字符
[^a-f] :a-f范圍外的任意一個字符
3、組合字符(大寫表示非)(該點都是匹配單個字符,要想匹配字串需要結合限定符來實作)
\d :匹配一個數字字符,等價于[0-9],
\D :匹配一個非數字字符,等價于[^0-9],
\w :匹配一個字母或一個數字或一個下劃線或一個漢字,
\W :匹配一個非字母、非數字、非下劃線和非漢字的字符,
\s :匹配一個任意的空白符,包括空格、制表符、換頁符等等,等價于[ \f\n\r\t\v],
\S :匹配任意一個非空白符,等價于[^ \f\n\r\t\v],
\b :匹配單詞的開始或結束的位置,
\B :匹配不是單詞開頭或結束的位置,
4、特殊字符
$ :表示字串的結尾位置(以什么結尾)
^ :表示字串的開始位置(以什么開始)(在取值范圍中還表示非)
. :一個點表示匹配一個除換行符 \n之外的任何單字符(匹配單個字符,要想匹配字串需要結合限定符來實作)
| :或者的意思,指明兩項之間的一個選擇 與[...]類似
\ :這個符號是用來轉義的
( ) :分組,標記一個子運算式的開始和結束位置
5、常用限定符
=================匹配次數=================
{m} :其前一單元嚴格出現m次(重復m次)
{m,} :其前一單元出現至少m次(重復m次或更多次)
{m,n} :其前一單元出現至少m次,最多n次(重復m到n次)
=======================================
=================多次匹配=================
* :其前面那個單元出現0次或任意次數(重復零次或更多次)
+ : 其前面那個單元出現1次或1次以上 至少匹配一次(重復一次或更多次)
? : 其前面那個單元出現0次或1次(重復零次或一次)懶惰匹配(盡可能短匹配)
=======================================
6、貪婪與懶惰(貪婪模式和非貪婪模式)(盡可能長匹配和盡可能短匹配)
*? 重復任意次,但盡可能少重復
+? 重復1次或更多次,但盡可能少重復
?? 重復0次或1次,但盡可能少重復
{n,m}? 重復n到m次,但盡可能少重復
{n,}? 重復n次以上,但盡可能少重復
7、分組
當用()定義了一個正則運算式組后,正則引擎則會把被匹配的組按照順序編號,存入快取,
默認情況下,每個分組會自動擁有一個組號,規則是:從左向右,以分組的左括號為標志,第一個出現的分組的組號為1,第二個為2,以此類推,
我們可以通過“\數字”的方式進行參考已經存入快取的組,\1參考第一個匹配的組,\2參考第二個組,以此類推,
括號內的內容會被當成一個整體進行匹配,
8、非獲取匹配和預查(零寬斷言)
非獲取匹配:是指正則引擎不會把被匹配的組存入快取,我們也無法通過“\數字”的方式進行參考我們的組,
預查:預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始,(即用來預查的運算式字串不會被消耗,它只是用于指定一個位置)
零寬斷言:用于查找在某些內容(但并不包括這些內容)之前或之后的東西,也就是說它們像\b,^,$那樣用于指定一個位置,這個位置應該滿足一定的條件(即斷言),因此它們也被稱為零寬斷言,
===========================================================================================
(?=exp)也叫零寬度正預測先行斷言,它斷言自身出現的位置的后面能匹配運算式exp,比如\b\w+(?=ing\b),匹配以ing結尾的單詞的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.時,它會匹配sing和danc,
(?<=exp)也叫零寬度正回顧后發斷言,它斷言自身出現的位置的前面能匹配運算式exp,比如(?<=\bre)\w+\b會匹配以re開頭的單詞的后半部分(除了re以外的部分),例如在查找reading a book時,它匹配ading,
===========================================================================================
(?:pattern) 非獲取匹配,匹配pattern但不獲取匹配結果,不進行存盤供以后使用,這在使用或字符“(|)”來組合一個模式的各個部分時很有用,例如“industr(?:y|ies)”就是一個比“industry|industries”更簡略的運算式,
(?=pattern) 非獲取匹配,正向肯定預查,在任何匹配pattern的字串開始處匹配查找字串,該匹配不需要獲取供以后使用,例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”,預查不消耗字符,也就是說,在一個匹配發生后,在最后一次匹配之后立即開始下一次匹配的搜索,而不是從包含預查的字符之后開始,
(?!pattern) 非獲取匹配,正向否定預查,在任何不匹配pattern的字串開始處匹配查找字串,該匹配不需要獲取供以后使用,例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”,
(?<=pattern) 非獲取匹配,反向肯定預查,與正向肯定預查類似,只是方向相反,例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”,
(?<!patte_n) 非獲取匹配,反向否定預查,與正向否定預查類似,只是方向相反,例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”,
9、其他常用正則匹配
匹配中文字符的正則運算式:[\u4e00-\u9fa5]
匹配雙位元組字符(包括漢字在內):[^\x00-\xff]
匹配中文、英文字母和數字及_:^[\u4e00-\u9fa5_a-zA-Z0-9]+$或[\u4e00-\u9fa5_a-zA-Z0-9_]{4,10}
只含有漢字、數字、字母、下劃線并且不能以下劃線開頭和結尾:^(?!_)(?!.*?_$)[a-zA-Z0-9_\u4e00-\u9fa5]+$
(?!_)表示不能以_開頭,(?!.*?_$)表示不能以_結尾
三、C#代碼呼叫正則運算式
命名空間 System.Text.RegularExpressions 1、new Regex(正則運算式).IsMatch(要匹配的字串) 回傳bool 2、Regex.Match Match match = Regex.Match("age=30", @"^(.+)=(.+)$"); if (match.Success) { Console.WriteLine(match.Groups[0].Value);//第0組 輸出完整的字串 age=30 Console.WriteLine(match.Groups[1].Value);//第1組 age Console.WriteLine(match.Groups[2].Value);//第2組 30 } 3、Regex.Matches StringBuilder sb = new StringBuilder(); sb.Append("<Name>張三</Name>\r\n<Name>李四</Name>\r\n<Name>王五</Name>"); MatchCollection mc = Regex.Matches(sb.ToString(), @"(?<=<Name>).*(?=</Name>)"); foreach (Match m in mc) { Console.WriteLine(m.Value); }
四、示例說明
接下來針對第二大點的內容我們舉些例子來說明:
示例1(普通字符):
我們用 xyh 來匹配 xyh123 如下圖所示:

從上面的正則運算式測驗器匹配的結果可以看出:如果直接寫多個普通字符,則會被當做一個整體的字串來匹配,
示例2(元字符和限定符):
我們用 \d 來匹配 xyh123 如下圖所示:

從匹配的結果可以發現\d只是匹配單個數字,所以有三個結果,分別為1、2、3,那如果想匹配一整個字串123要怎么辦呢?此時就要結合限定符來實作了,繼續來看下下面的一張圖,

從圖中可以看出結合限定符后就可以實作匹配到123這個字串了,
示例3(普通字符和元字符組合):
我們用 https://www\..+\.com 來匹配這么一句話:https://www.jd.com兩個鏈接https://www.taobao.com 如下圖所示:

可以發現匹配的結果為完整的一整句話,那為什么不是匹配出2個結果分別為 https://www.jd.com 和 https://www.taobao.com 呢?
那是因為默認情況下正則運算式采用貪婪模式匹配(即盡可能多匹配),所以匹配出了完整的一句話,此時可以用?來實作非貪婪模式匹配(即盡可能少匹配),如下圖所示:

這樣就匹配出了2個結果
示例4(分組):
我們用 (abc)\1 來匹配 abcabc666 如下圖所示:

從圖中可以看出匹配結果為abcabc,為什么會是這樣呢?首先我們分組(abc)匹配到存入快取中的值為abc,通過\1的方式就取到了存入快取中的第1個分組值abc,這個分組值abc與原來分組(abc)匹配到的字串abc組成新的匹配字串abcabc,用新的匹配字串abcabc去匹配abcabc666得到的匹配結果就是abcabc了,
示例5(非獲取匹配):
非獲取匹配(?:pattern)如下圖所示:


從圖中可以看出非獲取匹配,匹配pattern但不獲取匹配結果,不進行存盤供以后使用,因此無法通過“\數字”的方式來獲取,
示例6(預查和零寬斷言):
預查不消耗字符,它只是用于指定一個位置,如下圖所示:

從圖中可以看出用 ab(?=a) 來匹配 ababa123 時會得到兩個結果而不是一個結果,那是因為預查不消耗字符(即不會消耗用來預查用的運算式exp對應的字符),它只是用于指定一個位置,所以在第3個位置的a(即第2個a)沒有被消耗掉,當匹配到第1個結果ab后會從第3個位置的a(即第2個a)開始查找下一個能匹配的字串,而不是從第4個位置的b(即第2個b)開始查找,這就解釋了為什么會匹配到2個結果了,
PS:本文僅是個人見解 ,如有表述錯誤歡迎評論指正!
正則運算式測驗器:
鏈接:https://pan.baidu.com/s/1CwyrLH2dwbBk1KVi2FCGDw 提取碼:nwyc
著作權宣告:本文部分描述摘自網路,如有雷同純屬巧合,如有侵權請及時聯系本人修改,謝謝!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/8141.html
標籤:ASP.NET
上一篇:WebApi介面安全性 介面權限呼叫、引數防篡改防止惡意呼叫
下一篇:c#設計模式之單例模式
