標籤:
1. Regex
a. 什麼是Regex?
在編寫處理字串的程式或網頁時,經常會有尋找符合某些複雜規則的字串的需要。Regex就是用於描述這些規則的工具。換句話說,Regex就是記錄文本規則的代碼。Regex由literals(字面值)、metacharacters(元字元)兩類字元組成。字面值是你想要通配的字元,元字元是Regex使用的特殊字元,像是一種命令,使Regex具有相應功能。
b. Regex功能執行個體解析
假設你在一篇英文小說裡尋找hi,你可以使用Regexhi。
這幾乎是最簡單的Regex了,它可以精確匹配這樣的字串:由兩個字元組成,前一個字元是h,後一個是i。通常,處理Regex的工具會提供一個忽略大小寫選項,如果選中了這個選項,它可以匹配hi,HI,Hi,hI這四種情況中的任意一種。
不幸的是,很多單詞裡包含hi這兩個連續的字元,比如him,history,high等等。用hi來尋找的話,這裡邊的hi也會被找出來。如果要精確地尋找hi這個單詞的話,我們應該使用\bhi\b。\b是Regex規定的一個特殊代碼(好吧,某些人叫它元字元,metacharacter),代表著單詞開頭或結尾,也就是單詞的分界處。雖然通常英文的單詞是由空格,標點符號或者換行來分隔的,但是\b並不匹配這些單詞分隔字元中的任何一個,它只匹配一個位置。
這就是Regex的功能,在很多文字編輯器裡,用於檢索、替換那些符合某個模式的文本。
c. 在C#中使用Regex
Regex在.Net就是用字串表示,這個字串格式比較特殊,無論多麼特殊,在C#語言看來都是普通的字串,具體什麼含義由Regex類內部進行文法分析。
C#中分別對應Regex的三個重要方法。
1) IsMatch() 傳回值為bool類型
格式:Regex.IsMatch("字串", "Regex");
作用:判斷字串是否符合模板要求
例如:bool b =Regex.IsMatch("bbbbg","^b.*g$");判斷字串是否以b開頭且以g結尾,中間可以有其他字元,若正確返回true,否則else。
2) Match() 傳回值為Match類型,只能匹配一個
Matches() 傳回值為MatchCollection集合類型,匹配所有符合的
格式:Match match = Regex.Match("字串", "Regex");
或MatchCollection matches= Regex. Matches ("字串", "Regex");
作用:
①提取匹配的子字串
②提取組。Groups的下標由1開始,0中存放match的value。
例如:
1 Match match = Regex.Match("age=30", @"^(.+)=(.+)$");2 if (match.Success){ 3 Console.WriteLine(match.Groups[0] .Value);//輸出匹配的子字串4 Console.WriteLine(match.Groups[1] .Value);//擷取第一個分組的內容5 Console.WriteLine(match.Groups[2] .Value);//擷取第二個分組的內容6 }
1 MatchCollection matches = Regex.Matches("2010年10月10日", @"\d+");2 for (int i = 0; i < matches.Count; i++)3 {4 Console.WriteLine(matches[i].Value);5 }
3) Replace() 傳回值為string
1 //將所有的空格替換為單個空格 2 string str = " aa afds fds f "; 3 str = Regex.Replace(str, @"\s+", " "); 4 Console.WriteLine(str); 5 6 string str = "hello“welcome to ”beautiful “China”"; 7 //hello"welcome to "beautiful "China" 8 //$1表示引用第一組。$2表示用第二組。 9 string strresult = Regex.Replace(str, "“(.+?)”", "\"$1\"");10 Console.WriteLine(strresult);
貪婪與懶惰:
當Regex中包含能接受重複的限定符時,通常的行為是(在使整個運算式能得到匹配的前提下)匹配儘可能多的字元。以這個運算式為例:a.*b,它將會匹配最長的以a開始,以b結束的字串。如果用它來搜尋aabab的話,它會匹配整個字串aabab。這被稱為貪婪匹配。
有時,我們更需要懶惰匹配,也就是匹配儘可能少的字元。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它後面加上一個問號?。這樣.*?就意味著匹配任意數量的重複,但是在能使整個匹配成功的前提下使用最少的重複。
2. C#的async和await關鍵字
C# 5.0中引入了async 和 await。這兩個關鍵字可以讓你更方便的寫出非同步代碼。await 運算子應用於一個非同步方法呼叫的任務掛起方法的執行,直到等待任務完成。任務表示進行中的工作。
引用個例子:
1 public class MyClass 2 { 3 public MyClass() 4 { 5 DisplayValue(); //這裡不會阻塞 6 System.Diagnostics.Debug.WriteLine("MyClass() End."); 7 } 8 public Task<double> GetValueAsync(double num1, double num2) 9 {10 return Task.Run(() =>11 {12 for (int i = 0; i < 1000000; i++)13 {14 num1 = num1 / num2;15 }16 return num1;17 });18 }19 public async void DisplayValue()20 {21 double result = await GetValueAsync(1234.5, 1.01);//此處會開新線程處理GetValueAsync任務,然後方法馬上返回22 //這之後的所有代碼都會被封裝成委託,在GetValueAsync任務完成時調用23 System.Diagnostics.Debug.WriteLine("Value is : " + result);24 }25 }
上面在MyClass的建構函式裡調用了async關鍵字標記的非同步方法呼叫DisplayValue(),DisplayValue()方法裡執行了 一個await關鍵字標記的非同步任務GetValueAsync(),這個非同步任務必須是以Task或者Task<TResult>作為返回 值的,而我們也看到,非同步任務執行完成時實際返回的類型是void或者TResult,DisplayValue()方法裡 await GetValueAsync()之後的所有代碼都會在非同步任務完成時才會執行。
DisplayValue()方法實際執行的代碼如下:
1 public void DisplayValue()2 {3 System.Runtime.CompilerServices.TaskAwaiter<double> awaiter = GetValueAsync(1234.5, 1.01).GetAwaiter();4 awaiter.OnCompleted(() =>5 {6 double result = awaiter.GetResult();7 System.Diagnostics.Debug.WriteLine("Value is : " + result);8 });9 }
可以看到,async和await關鍵字只是把上面的代碼變得更簡單易懂而已。
程式的輸出如下:
MyClass() End.
Value is : 2.47032822920623E-322
參考內容:
http://www.cnblogs.com/youquan-deng/articles/csharp-regex.html
http://www.jb51.net/tools/zhengze.html#greedyandlazy
http://blog.csdn.net/tianmuxia/article/details/17675681
C#學習(五)- Regex等