正則的力量無法小覷,短短的幾個字元,往往勝過幾十行的**,大大可以簡化我們冗餘的**。
以前在js裡用正則比較多,今天來熟悉下c#中正則的使用方法,權當筆記了!
如果把正則當做一門語言的話,那麼正則的學習也和其他語言一樣,從歷史淵源到基本語法,從高階特性到效能優化,正則一樣不少。
歷史: 1
正規表示式的「祖先」可以一直上溯至對人類神經系統如何工作的早期研究。warren mcculloch 和 walter pitts 這兩位神經生理學家研究出一種數學方式來描述這些神經網路。 1956 年, 一位叫 stephen kleene 的數學家在 mcculloch 和 pitts 早期工作的基礎上,發表了一篇標題為「神經網事件的表示法」的**,引入了正規表示式的概念。正規表示式就是用來描述他稱為「正則集的代數」的表示式,因此採用「正規表示式」這個術語。 隨後,發現可以將這一工作應用於使用 ken thompson 的計算搜尋演算法的一些早期研究,ken thompson 是 unix 的主要發明人。正規表示式的第乙個實用應用程式就是 unix 中的 qed 編輯器。 如他們所說,剩下的就是眾所周知的歷史了。從那時起直至現在正規表示式都是基於文字的編輯器和搜尋工具中的乙個重要部分。
基本語法字元:
\d (代表0-9的數字)
\d (代表除數字以外的其他字元)
\w (代表所有的單詞字元-數字、字母、下劃線)
\w (代表所有除單詞字元外的字元)
\s (代表空白字元)
\s (代表除了空白字元以外的字元)
. (除了換行符外的任意字元)
[,,,] (匹配方括號內列出的所有字元)
[^,,,] (匹配方括號內列出的字元外的所有字元)
\b (匹配單詞邊界)
\b (匹配非單詞邊界)
^ (匹配字元開頭位置)
$ (匹配字元結尾位置)
(匹配n個符合條件的字元)
(匹配n到m個符合條件的字元)
(匹配大於等於n個符合條件的字元)
? (匹配1次或0次符合條件的字元)
+ (匹配一次或多次符合條件的字元)
* (匹配0次或多次符合條件的字元)
(a|b) (匹配符合a條件或者b條件的字元)
下面練習一些基本的例子來熟悉上面的基本語法
1.匹配3個數字,例如134 \d
2.匹配乙個單詞以字母開頭字母結尾中間是乙個或多個數字,例如a123b
^[a-za-z]\d+[a-za-z]$
3.匹配固定** 例如 021-81234563 或者 0512-81755456
^\d-\d
4.匹配正整數
[1-9][0-9]*
5.匹配兩位小數
(([0-9][1-9]*)|([1-9][0-9]*))+\.\d
6.匹配郵政編碼
^\d$
7.匹配手機號碼
^[1][3-9]\d$
8.匹配身份證號碼
^\d$)|^\d$
9.匹配漢字
^[\u4e00-\u9fa5]$
10.匹配url
上述是基本的使用語法,讓我們來看看c#中是如何使用它們的
system.text.regularexpressions.regex 這個事c#正則的使用類
他提供了如下方法來使用正則
1.ismatch 是否匹配-示例**:
1 //驗證手機號碼
2 public bool ismobile(string mobile) $");
4 }
2.split 根據條件切割字串
示例**
複製**
//根據數字拆分字串
public string splitstr(string str)
protected void btn_split_click(object sender, eventargs e) }}
複製**
3.replace
替換字串
1 //替換字串中的所有數字為指定字元
2 public string replaceword(string str1, string str2)
4.matches
獲取匹配集合
複製**
1 //驗證重複出現的詞(正則需要優化)
2 public string repeatwords(string str)
14 return repeatword;
15 }
16 else
19 }
複製**
正則的高階特性
1.分組和非捕獲性分組
組是把符合括弧中組條件的字元儲存起來,通過索引的方法供下面的匹配的呼叫
例如 需要匹配 abc123abc
我們可以這樣^(abc)123\1$,這裡的()即是乙個需要捕獲的組,他的條件是abc,這個時候在下乙個位置,我們只要通過\1就可以重複利用上一次捕獲過的值來匹配,如果有兩個分組,那我們獲取第二個分組就用\2
那在c#中如何利用呢?
string x = "abc123abc";
regex r = new regex(@"^(abc)123\1$");
if (r.ismatch(x))
這裡為何是groups[1]呢 因為在匹配的時候第乙個匹配的是符合所有條件的字串,然後儲存符合條件的組
我們也可以為組命名:
string x = "abc123abc";
regex r = new regex(@"^(?abc)123\1$");
if (r.ismatch(x))
這樣是不是就更加形象了呢
有的時候我們想匹配組但是不想儲存這個組匹配的內容,這個時候我們可以使用?:
1 string x = "abc123abc";
2 regex r = new regex(@"^(?:abc)123\1$");
3 if (r.ismatch(x))
4 2.貪婪模式和非貪婪模式
一般情況下,正則都是貪婪模式,尤其是在+或者*修飾的條件下,正則都會去盡可能的匹配更多的內容,但是如果新增了?號,這個時候立馬就會變成非貪婪模式
複製**
1 string x = "live for nothing,die for something";
2 regex r1 = new regex(@".*thing");
3 if (r1.ismatch(x))
4 7 regex r2 = new regex(@".*?thing");
8 if (r2.ismatch(x))
9 複製**
3.回溯與非回溯
在預設情況下正則匹配貪婪模式下,當匹配的字元陷入死胡同的時候,會進行回溯直到下乙個字元能夠接著匹配
比如 (.*)abc 來匹配123abc123abc 首先.*會進行貪婪匹配直到匹配到字元結尾的位置,接著匹配a,發現沒有字元可以匹配上,引擎就向後回溯,直到a匹配到最後abc中的a,然後緊接著匹配b,然後匹配c 所以結果是 123abc123abc
好,接著來說明下非回溯模式的執行過程,同樣首先.*像乙隻餓狼般的匹配到字元的結尾位置,這個時候開始匹配a 發現已經無法匹配,此模式下,不進行回溯,於是匹配失敗,在有的業務下我們需要這樣的非回溯匹配 ,語法例:(?>.*)abc
4.正向預搜尋反向預搜尋
不好解釋,舉例說明
正向預搜尋
複製**
string x = "1024 used 2048 free";
regex r1 = new regex(@"\d(?= used)");
if (r1.matches(x).count==1)
regex r2 = new regex(@"\d(?! used)");
if (r2.matches(x).count==1)
複製**
r1表示匹配後面緊跟著used的四個數字 於是乎匹配了1024 r2 匹配後面不是緊跟著used的四個數字 於是乎 匹配2048
反向預搜尋
複製**
string x = "used:1024 free:2048";
regex r1 = new regex(@"(?<=used:)\d");
if (r1.matches(x).count==1)
regex r2 = new regex(@"(?
if (r2.matches(x).count==1)
複製**
r1匹配前面緊著著used:的四個數字 於是乎匹配1024 r2匹配前面不是緊跟著used:的四個數字 於是乎撇配2048
C 正則學習雜談(三)
五 一些常用正則 1 匹配任意中文字元 u4e00 u9fa5 2 匹配手機的正則 1 3 d 5 389 d 3 匹配座機的正則 格式 010 12345678 區號可有可無,座機號為7或8位 0 10 2 0 57 9 3 9 d d 4 日期正則 格式為yyyy mm dd,或yyyy m d...
正則學習筆記
最近做東西頻繁的用到正則這一塊,所以自己又翻了翻以前的筆記和檢視了正則三十分鐘入門教程。重新整理了筆記,希望在以後的學習過程中便於查閱 注 以下例子非本人原創 什麼是正規表示式 在編寫處理字串的程式或網頁時,經常會有查詢符合某些複雜規則的字串的需要。正規表示式就是用於描述這些規則的工具。換句話說,正...
正則學習三
開始閱讀 正規表示式 這本書 這本書講得挺好的,序言寫得很好。學每一樣東西應該以 登堂入室 為最低標準 提高對自己的要求才能提高自己的技術 1.正則的理解應該以單個字元為單位去理解,如 cat 不應該理解 成 以 cat 開頭,而且應該理解成 以 c 開頭 其次 是 at 對於 和 書中有詳細描述,...