第4章 操作字符串
開發人員在實際開發過程中,對字符串的操作是經常遇到的,其中涉及字符串拼接、拆分、比較、替換等操作。Visual C#對于文字的處理大多是通過對字符和字符串的操作來進行的,同時還為開發人員提供了功能強大的函數。本章向讀者介紹C#中的字符串操作,首先介紹C#字符串類型,然后結合實例講解字符串的各種操作,最后介紹正則表達式和C# 4.0新特性之智能提示的改進。
4.1 C#字符串類型
Visual C#提供了String類型,String和StringBuilder兩種類來對字符串進行處理。string是.NET Framework中String的別名,string也是C#基本類型,String是Visual C#中一個功能非常強大、用途非常廣泛的基類。string與String實質上沒什么區別,只是在C#的編譯時,會自動的把string轉化為System.String,多做一次轉換。因此,在編碼時推薦使用String。StringBuilder類主要用于長字符串的操作,StringBuilder表示可變字符串,它允許用戶有效地對字符串的字符執行動態操作,有效地縮減字符串的大小或者更改字符串中的字符。
4.1.1 格式化字符串
格式化字符串是指字符串可以按照設定的格式輸出顯示。在C#字符串操作中,經常在類和結構中執行ToString()方法來顯示給定變量的內容。但是,根據實際需求,用戶常常希望以各種可能的方式顯示變量的內容,在不同的文化或地區背景中有不同的格式。例如.NET System.DateTime基類,用格式化字符串操作可以把日期顯示為2010-5-26、2010年5月26日、5月6日、2010年5月等格式。格式化字符串可以用ToString()方法和Format()方法。
(1)ToString()格式:
Public string ToString(string format)
參數說明:
? format:用來指定字符串所要格式化的形式。
? ToString()是對實例對象本身進行格式化。
用法:
double num=1.23456 //定義double變量num num.ToString(C) //把num格式化為貨幣格式的字符
(2)Format()格式:
Public static string Format(string format, object obj)
? 參數說明:format用來指定字符串所要格式化的形式。Obj表示要被格式化的對象。
? 返回值:format的一個副本。
用法:
DateTime dt = DateTime.Now; //獲取系統當前日期 string strB = string.Format("{0:D}", dt);//格式化成短日期格式
1.格式化數字
首先介紹數字的格式化,表4-1所示是數字格式字符的相關說明。
表4-1 格式化數字符屬性表

【實例4-1】本例將創建一個控制臺應用程序,實現格式化數字。
(1)創建控制臺應用程序。
啟動Visual Studio 2010,選擇“文件”→“新建”菜單命令,在“新建”選項卡中選擇“項目”,創建一個名稱為“4.1”的控制臺應用程序。
(2)在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 static void Main(string[] args) 02 { 03 double val=Math.PI; 04 Console.WriteLine(val.ToString( )); 05 Console.WriteLine(val.ToString("C")); 06 Console.WriteLine(val.ToString("E")); 07 Console.WriteLine(val.ToString("F3")); 08 int val1 = 65535; 09 Console.WriteLine(val1.ToString("D")); 10 Console.WriteLine(val1.ToString("x")); 11 Console.WriteLine(val1.ToString("X")); 12 Single val2 = 0.123F; 13 Console.WriteLine(val2.ToString("p")); 14 Console.WriteLine(val2.ToString("p1")); 15 System.Console.ReadLine();//讀取Enter鍵之后,關閉控制臺應用程序 16 }
【代碼解析】第4~14行按照不同的格式將數字格式化輸出。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-1所示。

圖4-1 格式化數字輸出結果
2.格式化日期
格式化日期字符屬性表如表4-2所示。
表4-2 格式化日期字符屬性表

【實例4-2】本例將創建一個控制臺應用程序,實現格式化數字的例子,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 static void Main(string[] args) 02 { 03 DateTime dt = DateTime.Now; 04 Console.WriteLine(dt.ToString( )); 05 Console.WriteLine(dt.ToString("d")); 06 Console.WriteLine(dt.ToString("D")); 07 Console.WriteLine(dt.ToString("f")); 08 Console.WriteLine(dt.ToString("F")); 09 Console.WriteLine(dt.ToString("g")); 10 Console.WriteLine(dt.ToString("G")); 11 Console.WriteLine(dt.ToString("M")); 12 Console.WriteLine(dt.ToString("R")); 13 Console.WriteLine(dt.ToString("s")); 14 Console.WriteLine(dt.ToString("t")); 15 Console.WriteLine(dt.ToString("T")); 16 Console.WriteLine(dt.ToString("u")); 17 Console.WriteLine(dt.ToString("U")); 18 Console.WriteLine(dt.ToString("y")); 19 System.Console.ReadLine();//讀取Enter鍵之后,關閉控制臺應用程序 20 }
【代碼解析】第4~18行按照不同的日期格式將當前日期格式化輸出。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-2所示。

圖4-2 格式化日期輸出結果
4.1.2 比較字符串
C#中字符串的比較用String類實現,String類提供了多種方法對字符串進行比較,這里重點對常用4種方法進行介紹,分別是Compare()、CompareTo()、CompareOrdinal()、Equals()。
1.Compare()方法
Compare()方法用來比較兩個字符串是否相等,Compare()提供了將當前字符串對象與另一個字符串或對象進行全面比較的方法,此方法識別區域性。可以使用此方法來比較兩個字符串或兩個字符串的子串。另外,還提供了考慮或忽略大小寫與區域性差異的重載。Compare()方法是CompareTo()方法的靜態版本。Compare()方法有很多個重載方法,下面介紹最常用的方法。格式:
Public int Compare(string str1,string str2)
? 參數說明:str1和str2代表要比較的兩個字符串。
? 返回值:如果str1等于str2則返回0,如果str1大于str2則返回1,如果str1小于str2返回-1。
Tips
比較字符串,并不是比較字符串的長度,而是從首字符開始逐個比較字符的大小,如果已分出大小則結束比較,大于則返回1,小于則返回-1,如果相等則繼續比較下一個字符直到分出大小或到字符串尾,如仍相等則返回0。
字符的大小,如果是英文字母按照a到z的順序依次增大,也就是a小于b,小寫字母小于大寫字母,小寫字母大于單個數字字符;如果是漢字比較,則比較漢語拼音字母的大小。
【實例4-3】本例將創建一個控制臺應用程序,聲明兩個字符串變量,然后使用Compare方法比較兩個字符串大小,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 06 namespace Ch4Demo2 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 13 string str1, str2; //聲明兩個字符串str1、str2 14 str1="張三"; 15 str2="李四"; 16 Console.WriteLine(string.Compare(str1, str2));//比較兩字符串,輸出比較結果 17 str2 = "張三"; 18 Console.WriteLine(string.Compare(str1, str2)); 19 str2 = "張昭"; 20 Console.WriteLine(string.Compare(str1, str2)); 21 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 22 23 } 24 } 25 }
【代碼解析】第16行使用Compare()函數比較兩字符串,輸出比較結果。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-3所示。

圖4-3 比較字符串Compare()方法輸出結果
2.CompareTo()方法
CompareTo()方法與Compare()方法相似,都可以比較兩個字符串是否相等,不同的是CompareTo()方法以實例對象本身與指定的字符串作比較。格式:
public int CompareTo (string str)
? 參數說明:str表示與此字符串相比較的字符串。
? 返回值:返回值與Compare()方法相同。
【實例4-4】本例將創建一個控制臺應用程序,聲明兩個字符串變量,然后使用CompareTo()方法比較兩個字符串大小,在控制臺項目Program.cs文件的main函數中輸入下面代碼。
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 06 namespace Ch4Demo2 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 13 string str1, str2; //聲明兩個字符串str1、str2 14 str1="張三"; 15 str2="李四"; 16 Console.WriteLine(str1.CompareTo(str1)); //比較兩字符串,輸出比較結果 17 Console.WriteLine(str1.CompareTo(str2)); 18 Console.WriteLine(str2.CompareTo(str1)); 19 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 20 } 21 } 22 }
【代碼解析】第16行使用CompareTo()函數比較兩字符串,輸出比較結果。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-4所示。

圖4-4 比較字符串CompareTo()方法輸出結果
3.Equals()方法
Equals()方法主要用于比較兩個字符串是否相同,如果相同返回值為true,否則為false。只要使用“=”運算符,就會調用Equals()方法,Equals()方法與“=”是等價的。其常用的兩種語法格式如下:
Public bool Equals (string str) Public static bool Equals(string str1,string str2)
? 參數說明:str表示與實例比較的字符串。str1和str2表示要進行比較的兩個字符串。
? 返回值:如果兩個值相同,則為true,否則為false。
【實例4-5】本例將創建一個控制臺應用程序,聲明兩個字符串變量,然后使用Equals( )方法比較兩個字符串是否相同,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 06 namespace Ch4Demo2 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 13 string str1, str2; //聲明兩個字符串str1、str2 14 str1="張三"; 15 str2="李四"; 16 Console.WriteLine(str1.Equals(str1)); //比較兩字符串, 輸出比較結果 17 Console.WriteLine(string.Equals(str1,str2)); 18 System.Console.ReadLine(); //讀取“Enter”鍵之后, 關閉控制臺應用程序 19 20 } 21 } 22 }
【代碼解析】第16行使用Equals()函數比較兩個字符串,輸出比較結果。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-5所示。

圖4-5 比較字符串Equals()方法輸出結果
4.CompareOrdinal()方法
CompareOrdinal()方法比較兩個字符串對象而不考慮本地區域性。其常用語法格式如下:
Public int CompareOrdinal (string str1,string str2)
? 參數說明:str1和str2代表要比較的兩個字符串。
? 返回值:如果str1等于str2則返回0,如果不等則返回str1減去str2的值。
【實例4-6】本例將創建一個控制臺應用程序,聲明兩個字符串變量,然后使用CompareOrdinal()方法比較兩個字符串是否相同,如果str1等于str2則返回0,如果不等則返回str1減去str2的值,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 06 namespace Ch4Demo2 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 13 string str1, str2; //聲明兩個字符串str1、str2 14 str1="e"; 15 str2="b"; 16 Console.WriteLine(string.CompareOrdinal(str1,str2));//比較兩字符串,輸出比較結果 17 str2 = "e"; 18 Console.WriteLine(string.CompareOrdinal(str1, str2)); 19 str2 = "a"; 20 Console.WriteLine(string.CompareOrdinal(str1, str2)); 21 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 22 } 23 } 24 }
【代碼解析】第16行使用CompareOrdinal()函數比較兩個字符串,輸出比較結果。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-6所示。

圖4-6 比較字符串CompareOrdinal()方法輸出結果
4.1.3 連接字符串
C#為開發用戶提供了兩種方法實現字符串的連接,第一種使用“+”號連接字符串,這種方法使用起來非常簡單,但在連接過程中會將新的組合字符串分配新的空間,在一個較大的循環中會占用過多的資源,因此“+”號一般適用于低數量級字符串連接;另一種使用StringBuild類的Append()方法來連接字符串,此方法對字符串的處理效率要比“+”號高很多,如果對大量字符串進行連接,建議使用Append()方法。下面詳細介紹這兩種方法。
1.“+”號連接字符串
“+”號用來連接兩個字符串,使用格式如str1+str2。
【實例4-7】本例將創建一個控制臺應用程序,控制臺輸出兩個字符串的連接,在控制臺項目Program.cs文件的main函數中輸入下面代碼。
01 using System; 02 using System.Collections.Generic; 03 using System.Linq 04 using System.Text; 05 06 namespace StrAdd 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 string str, str1, str2; //聲明三個字符串str,str1,str2變量 13 str1 = "Hello"; 14 str2 = "World"; 15 str = str1 + str2; //字符串連接 16 Console.WriteLine(str); 17 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 18 } 19 } 20 }
【代碼解析】第15行將兩個字符串連接在一起。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的【啟動調試】按鈕,顯示結果如圖4-7所示。

圖4-7 運行結果
2.Append()方法連接字符串
Append()方法屬于StringBuild類,該方法的功能是使用實例對象本身與指定的字符串連接,語法格式如下:
Public StringBuild CompareTo (char[ ] str)
? 參數說明:str代表要連接的字符串。
? 返回值:該方法返回一個StringBuild對象。
【實例4-8】本例將創建一個控制臺應用程序,控制臺輸出兩個字符串的連接,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq 04 using System.Text; 05 06 namespace StrAdd 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 13 string str1, str2; //聲明兩個字符串str1、str2變量 14 StringBuilder sb=new StringBuilder(); //實例化StringBuilder類對象sb 15 str1 = "Hello"; 16 str2 = "World"; 17 sb.Append(str1); //字符串連接 18 sb.Append(str2); //字符串連接 19 Console.WriteLine(sb.ToString()); 20 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 21 } 22 } 23 }
【代碼解析】第14行實例化StringBuilder類對象sb。第17~18行將兩個字符串使用StringBuilder的對象連接在一起。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-8所示。

圖4-8 運行結果
4.1.4 復制字符串
在程序開發中可能經常需要對字符串進行復制操作,C#提供了Copy()和CopyTo()方法來實現對字符串的復制,這兩個方法都屬于String類。下面詳細介紹這兩種方法。
1.CopyTo()方法
CopyTo()方法將指定段中的字符復制到目標字符數組的指定段中。復制StringBuilder類的實例的內容可以使用CopyTo()方法,語法格式如下:
public void CopyTo(int sourceIndex,char[ ] destination,int destinationIndex,int count)
參數說明:
? sourceIndex指定開始復制字符的位置。
? destination指定要將字符復制到的字符數組。
? destinationIndex指定要將字符復制到的destination參數中的起始位置。
? count指定要復制的字符數。
【實例4-9】本例將創建一個控制臺應用程序,在控制臺項目程序中,把str1字符串“Hello World”中的“World”復制到str2中,并在str2中從第2個元素開始存放,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq 04 using System.Text; 05 06 namespace StrCopy 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 string str1 = "Hello World"; 13 char[] str2 = new char[20]; //定義字符數組 14 str1.CopyTo(6,str2, 1, 5); //從第7個字符開始,復制5個字符 15 Console.WriteLine(str2); //輸出字符串 16 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 17 } 18 } 19 }
【代碼解析】第14行從第7個字符開始,復制5個字符。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-9所示。

圖4-9 運行結果
2.Copy()方法
Copy()方法創建一個與指定的String具有相同值的String的新實例,此方法是一個靜態方法,其語法格式如下:
public static string Copy(string str)
? 參數說明:str為要復制的String。
? 返回值:與str具有相同值的新String。
【實例4-10】本例將創建一個控制臺應用程序,在控制臺項目程序中,把str1字符串“Hello World”,復制到str2中,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq 04 using System.Text; 05 06 namespace StrCopy 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 string str1 ,str2; 13 str1 = "Hello World"; 14 str2=String.Copy(str1); //將字符串str1復制到str2中 15 Console.WriteLine(str2); //輸出字符串 16 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 17 } 18 } 19 }
【代碼解析】第14行將字符串str1復制到str2中。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-10所示。

圖4-10 運行結果
4.1.5 截取字符串
C#提供了Substring()方法來截取字符串,該方法屬于String類。通過Substring()可以截取字符串中指定位置和指定長度的字符。其語法格式如下:
Public string Substring(int startIndex,int length)
? 參數說明:startIndex指定要截取子字符串起始位置的索引;length指定要截取的長度。
? 返回值:返回一個String,它等于此實例中從startIndex開始的長度為length的子字符串,如果startIndex等于此實例的長度且length為零,則為空。
【實例4-11】本例將創建一個控制臺應用程序,聲明兩個string類型的變量str1和str2,并將str1賦值為“C#截取字符串實例”,然后使用Substring方法從str1字符串的索引2處開始截取5個字符,然后輸出,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 06 namespace Strsub 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 string str1, str2; //聲明兩個字符串變量str1、str2 13 str1 = "C#截取字符串實例"; //賦值 14 str2=str1.Substring(2,5); //截取字符串 15 Console.WriteLine(str2); //輸出截取結果 16 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 17 } 18 } 19 }
【代碼解析】第14行截取字符串。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-11所示。

圖4-11 運行結果
4.1.6 替換字符串
C#為開發人員提供了Replace()方法來實現字符串的替換,Replace()方法可以替換掉一個字符串中的某些特定字符或者子串。其語法格式如下:
Public string Replace(char OldChar,char NewChar) Public string Replace(string OldValue,string NewValue,)
參數說明如表4-3所示。
表4-3 Replace方法參數表

第一種格式主要用于替換字符串中的單個字符,第二種格式主要替換字符串中的子串。當然子串也可以是單個字符,即也可以用第二種格式實現單個字符的替換。下面用實例來說明。
【實例4-12】本例將創建一個控制臺應用程序,聲明一個string類型變量str1,并賦值為“Hello Boys”;然后使用Replace方法的第一種語法格式將字符串str1中的“o”替換成“#”,使用第二種語法格式將字符串str1中的“Boys”替換成“Girls”,使用第二種語法格式將字符串str1中的“o”替換為“test”;最后分別輸出替換后的字符串,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 06 namespace SrtReplace 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 13 string str1, str2,str3,str4; //聲明4個字符串變量 str1、str2、str3、str4 14 str1 = "Hello Boys"; //賦值 15 str2=str1.Replace('o','#'); //替換單個字符 16 str3 = str1.Replace("Boys", "Girls"); //替換字符串 17 str4 = str1.Replace("o", "test"); //替換字符串 18 Console.WriteLine(str2); //輸出替換結果 19 Console.WriteLine(str3); //輸出替換結果 20 Console.WriteLine(str4); //輸出替換結果 21 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 22 } 23 } 24 }
【代碼解析】第15行替換單個字符,第16行替換字符串。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-12所示。

圖4-12 替換字符串輸出結果
4.1.7 分割字符串
在程序設計過程中經常需要分割字符串,如獲取字符串“河南,山東,廣東,四川,江蘇”中的單個省份,這就需要對字符串進行分割。C#提供了String類的Split方法來實現,該方法用于分割字符串,其返回值是包含所有分割子字符串的數組對象,可以通過數組取得所有分割的子字符串。Split方法語法格式如下:
Public string [ ] Split(char[ ]separator);
? 參數說明:separator為一個字符數組,用于包含分隔符。
? 返回值:返回一個數組,數組中存放分割后的單個子字符串,這些子字符串由separator中的一個或多個字符分割。
下面用實例來說明。
【實例4-13】本例將創建一個控制臺應用程序,聲明一個string類型變量str1,賦值為“河南,山東,廣東,四川,江蘇”,分割變量str1,并輸出分割后的字符串,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 06 namespace ChrSplit 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 string str1; //聲明字符串變量str1 13 string[ ] str2=new string[20]; //聲明長度為20的字符數組變量 14 str1 = "河南,山東,廣東,四川,江蘇"; //賦值 15 char[ ] sp = { ',', '.' }; //分割字符 16 str2=str1.Split(sp); //分割字符串 17 for (int i = 0; i < str2.Length; i++) 18 { 19 Console.WriteLine(str2[i]); //輸出分割結果 20 } 21 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 22 } 23 } 24 }
【代碼解析】第15~16行分割字符串。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-13所示。

圖4-13 Split分割字符輸出結果
4.2 正則表達式
本節將介紹正則表達式的概念、正則表達式的作用及表達式的操作,然后利用一些例子來解釋正則表達式的用法。
正則表達式是指一個用來描述或者匹配一系列符合某個句法規則的字符串的單個字符串,一個正則表達式,就是用某種模式去匹配一類字符串的一個公式。它主要用來對字符串進行檢驗和操作,正則表達式功能非常強大。正則表達式常見運用是驗證用戶所輸入信息格式是否正確,例如驗證郵件地址是否合法可以用此正則表達式“[\w\.-]+(\+[\w-]*)?@([\w-]+\.)+[\w-]+”。當然正則表達式不僅僅是用于驗證,可以說只要運用字符串的地方都可以使用正則表達式。
C#中正則表達式擁有一套語法規則,常見語法包括字符匹配、重復匹配、字符定位、轉義匹配和其他高級語法(字符分組、字符替換和字符決策)。接下來詳細介紹C#表達式語法規則。
1.字符匹配語法(見表4-4)
表4-4 字符匹配語法表

2.重復匹配語法(見表4-5)
表4-5 重復匹配語法表

3.字符定位語法(見表4-6)
表4-6 字符定位語法表

4.轉義匹配語法(見表4-7)
表4-7 轉義匹配語法表

要想真正用好正則表達式,正確地理解各語法規則非常重要。下面的一節中將向讀者介紹正則表達的用法操作。
4.2.1 基本的正則表達式操作
通過上面正則表達式概念和語法規則的介紹,讀者已經了解正則表達式的語法基礎,接下來介紹如何構建正則表達式。C#中使用正則表達式需要引用命名空間“System.Text.Regular Expressions”,該命名空間包括了8個基本的類:Capture、CaptureCollection、Group、GroupCollection、Match、MatchCollection、Regex和RegexCompilationInfo。各類的說明如表4-8所示。
表4-8 正則表達式類說明

構建正則表達式經常需要用到Regex類,Regex類中包括一些常用方法:IsMatch()、Replace()、Split()、Replace()、Split()和操作字符串中4.1.6、4.1.7節所介紹的功能基本相同,這里詳細介紹IsMatch()方法。
IsMatch()方法用來判斷字符串是否滿足正則表達式要求,如果滿足返回True,相反則返回False,語法格式如下:
Public bool IsMatch(String input,String pattern)
? 參數說明:input為輸入字符串,即需要比較的字符串;pattern為正則表達式。
? 返回值:輸入字符串滿足正則表達式要求返回True,否則返回False。
【實例4-14】本例將創建一個控制臺應用程序,使用正則表達式判斷電話號碼是否為北京地區的電話號碼。首先北京地區電話區號為“010”,后面電話號碼位數為8,例如“01088888888”。使用正則表達式的語法規則可進行限定,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 using System.Text.RegularExpressions; 06 07 namespace RegExpMatch 08 { 09 class Program 10 { 11 static void Main(string[] args) 12 { 13 string str1,str2,strreg; //聲明字符串變量str1,str2,strreg 14 strreg = "010\\d{8,8}"; //正則表達式 15 str1 = "01012345678"; //賦值電話號碼 16 str2 = "02012345678"; //賦值電話號碼 17 Console.WriteLine("是否北京電話號碼 18 "+Regex.IsMatch(str1,strreg).ToString()); //輸出判斷結果 19 Console.WriteLine("是否北京電話號碼"+Regex.IsMatch(str2,strreg).ToString()); 20 輸出判斷結果 21 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 22 } 23 } 24 }
【代碼解析】第14行初始化正則表達式,第17行判斷輸出結果。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-14所示。

圖4-14 IsMatch方法輸出結果
接下來就用Regex類對象來構建正則表大達式,Regex對象的構造函數包括兩個重載,一個是不含參數的構造函數,另外一個是含有參數的構造函數,格式如下:
基本形式Regex(string pattern); 重載形式Regex(string pattern,RegexOptions);
參數說明:
? pattern是指正則表達式。
? RegexOptions屬于枚舉類型,包括IgnoreCase(忽略大小寫)、ReghtToLeft(從右向左)、None(默認)、CultureInvariant(忽略區域)、Multline(多行模式)和SingleLine(單行模式)。
【實例4-15】本例將創建一個控制臺應用程序,構建一個正則表達式判斷輸入的電子郵箱地址是否合法。首先讀者可以分析一下電子郵箱的格式,例如“123xyz@163.com”,可以看出“@”之前是任意單字字符,可以用“\w”加以匹配,“@”和“.”之間也是任意單字字符,整個正則表達式可以寫成“\\w{1,}@\\w{1,}\\.”,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 using System.Text.RegularExpressions; 06 07 namespace StrRegex 08 { 09 class Program 10 { 11 static void Main(string[] args) 12 { 13 string str1,strreg; //聲明字符串變量str1、strreg 14 strreg = "\\w{1,}@\\w{1,}\\."; //正則表達式 15 Regex Emain_reg = new Regex(strreg); //實例化Regex類對象 16 do //循環輸入,直到輸入合法郵箱地址 17 { 18 Console.WriteLine("請輸入電子郵箱地址"); 19 str1 = Console.ReadLine(); 20 if (Emain_reg.IsMatch(str1) == true) 21 { 22 Console.WriteLine("恭喜,你輸入的郵箱地址合法");//輸出判斷結果 23 break; //輸入合法地址則結束循環 24 } 25 else 26 Console.WriteLine("對不起,你輸入的,郵箱地址有誤");//輸出判斷結果 27 } 28 while (true); //無條件循環 29 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 30 } 31 } 32 }
【代碼解析】第14行初始化正則表達式,第15行實例化Regex類對象,第20行判斷輸入的郵箱是否合法。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-15所示。

圖4-15 電子郵箱驗證輸出結果
4.2.2 深入了解正則表達式
通過4.2.1節介紹讀者了解了正則表達式的構建,可以按照正則表達式語法規則寫出簡單的正則表達式,這一節將更加深入地介紹正則表達式的使用。
1.二選一匹配
C#正則表達式中的“(|)”符號可以實現對字符的其中之一進行匹配,像[a-z]也是一種匹配,只不過它只能匹配單個字符,而“(|)”則提供了更大的范圍。例如(ab|xy)表示匹配ab或匹配xy。注意“|”與“()”在此是一個整體。下面提供一些簡單的實例。
【實例4-16】本例將創建一個控制臺應用程序,正則表達式二選一匹配實例如下,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System.Linq; 02 using System.Text; 03 using System.Text.RegularExpressions; 04 namespace Ch4Demo2 05 { 06 class Program 07 { 08 static void Main(string[] args) 09 { 10 string str1,str2,str3,strreg; //聲明字符串變量str1、 str2、str3、strreg 11 strreg = "hello (boy|girl)s"; //正則表達式 12 str1 = "hello boys"; //賦值 13 str2 ="hello girls"; //賦值 14 str3 = "hello boy and girls"; //賦值 15 Console.WriteLine(Regex.IsMatch(str1,strreg).ToString()); //輸出判斷結果 16 Console.WriteLine(Regex.IsMatch(str2,strreg).ToString()); //輸出判斷結果 17 Console.WriteLine(Regex.IsMatch(str3,strreg).ToString()); //輸出判斷結果 18 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 19 } 20 } 21 }
【代碼解析】第11行初始化正則表達式,第15行輸出判斷結果。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-16所示。

圖4-16 二選一匹配輸出結果
2.貪婪與非貪婪
C#中正則表達式的引擎是貪婪的,只要模式允許,它將匹配盡可能多的字符。例如,“.”匹配任意字符,“*”匹配0個或多個字符,“+”匹配一個或多個字符。通過在“重復描述字符”(*、+)后面添加“?”,可以將匹配模式改成非貪婪。
【實例4-17】本例將創建一個控制臺應用程序,使用正則表達式匹配以“s”結束的字符串,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 using System.Text.RegularExpressions; 06 namespace Regtl 07 { 08 class Program 09 { 10 static void Main(string[] args) 11 { 12 string str1; //聲明字符串變量str1 13 str1 = "hello boys and girls"; //賦值 14 Regex strreg1 = new Regex(@".*s"); //實例化Regex類對象 15 if(strreg1.IsMatch(str1)) 16 { 17 Console.WriteLine("匹配結果:" + strreg1.Match(str1).Value); } 18 Regex strreg2 = new Regex(@".*?s"); //實例化Regex類對象 19 if(strreg2.IsMatch(str1)) 20 { 21 Console.WriteLine("匹配結果:" + strreg2.Match(str1).Value); 22 } 23 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 24 } 25 } 26 } 27 }
【代碼解析】第14行實例化Regex類對象,第19~22行進行匹配判斷。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-17所示。

圖4-17 貪婪與非貪婪輸出結果
Tips
“Regex strreg1 = new Regex(@".*s")”語句實例化一個Regex類對象,正則表達式為“.*s”,表示以s結束的任意字符串,@非正則表達式成員,它的作用與轉義字符“\”、的作用相同,如下面兩條語句等價。
string x="D:\\test\\test.cs"; string y = @"D:\test\\test.cs";
Match()方法查找第一次滿足正則表達式的字符串,由于貪婪匹配,所以Match()方會匹配整個字符串,也就是圖中的第一次輸出結果,當使用非貪婪匹配“.*?s”時,Match()方法查到“hello boys”滿足正則表達式條件而結束。
“?”能強制量詞盡可能少地匹配字符,常用的非貪婪字符有:“*?”、“+?”、“??”、“{n}?”、“{m,n}?”等。
3.捕獲和反向引用
正則表達式引擎會記憶“()”中匹配到的內容,作為一個“組”叫做捕獲組,并且可以通過索引的方式進行引用。捕獲組(capturegroup)就像是正則表達式中的變量。捕獲組可以捕獲正則表達式中的字符模式,并且由正則表達式后面的編號或名稱來引用。
說明:
? ():用來捕獲其中的字符串
? \數字:用編號來引用
【實例4-18】本例將創建一個控制臺應用程序,運行正則表達式匹配字符串“A<i>quantifier</i>canbe<big>greedy</big>”中的“<></>”內容。分析可知<i>與</i>可以捕獲組加以引用,在控制臺項目Program.cs文件的main函數中輸入下面代碼:
01 using System; 02 using System.Collections.Generic; 03 using System.Linq; 04 using System.Text; 05 using System.Text.RegularExpressions; 06 07 namespace Ch4Demo2 08 { 09 class Program 10 { 11 static void Main(string[] args) 12 { 13 string str1; //聲明字符串變量str1 14 str1 = "A<i>quantifier</i>canbe<big>greedy</big>"; //賦值 15 Regex strreg1 = new Regex(@"<(\w+)>.*</\1>"); //實例化Regex類對象 16 if (strreg1.IsMatch(str1)) 17 { 18 Console.WriteLine("匹配數:"+strreg1.Matches(str1).Count.ToString()); 19 Console.WriteLine("匹配結果1:" + strreg1.Match(str1).Value); 20 Console.WriteLine("匹配結果2:" + strreg1.Match(str1). NextMatch().Value); 21 //輸出結果 22 } 23 Regex strreg2 = new Regex(@".*?s"); //實例化Regex類對象 24 System.Console.ReadLine(); //讀取“Enter”鍵之后,關閉控制臺應用程序 25 } 26 } 27 }
【代碼解析】第15行實例化Regex類對象,第16~22行進行匹配判斷。
【運行效果】代碼編寫完成之后,按“F5”鍵或者單擊工具欄中的“啟動調試”按鈕,顯示結果如圖4-18所示。

圖4-18 捕獲和反向引用
Tips
“Regex strreg1 = new Regex(@”<(\w+)>.*</\1>“)”語句實例化一個Regex類對象,正則表達式 “<(\w+)>.*</\1>”可分為三部分。第一部分“<(\w+)>”匹配以字符“<”開始,以“>”結束,中間“(\w+)”代表任意字符;第二部分“.*”代表任意字符;第三部分“</\1>”,“\1”是在對第一部分中“(\w+)”的組引用。Matches()方法中的Count屬性返回的是滿足匹配的個數。利用Match()的NextMatch()方法可以輸出下一個滿足條件的匹配。
4.3 C# 4.0中的新特性:智能提示的改進
在Visual Studio 2008中,為一個對象選擇屬性時,它將根據輸入的字母的順序排列,為開發人員提供智能提示。而在Visual Studio 2010中它將向開發人員顯示基于組的屬性,例如,如果在文本框對象后鍵入text,它將向用戶顯示Text,TextChanged,TextMode。它也支持Pascal的智能提示,例如,用戶輸入TC,它將導航TextChanged成員。
為幫助示范這個Visual Studio 2010中的智能提示的改進,先來在Visual Studio 2008中做一個簡單的例子,在Forms窗口中添加一個textBox控件,在后臺代碼設置其text屬性,當鍵入tex時系統提示如圖4-19所示。可以看出提示所有屬性或方法都是以te開始的,如果開發人員使用的是text屬性這個提示當然很好,但開發人員想使用AppendText()方法,這個提示就不行了。

圖4-19 Visual Studio 2008的智能提示
Visual Studio 2010中做了修改,當在Visual Studio 2010中鍵入“tex”時,會發現Appendtext也顯示在其中,如圖4-20所示。這允許很快地看到與text相關的所有方法/屬性/事件,更快地找到開發人需要的東西。

圖4-20 Visual Studio 2010中的代碼智能提示
1.搜尋關鍵詞
Visual Studio 2010的這個新的智能提示過濾特性在搜尋任何成員時都會非常有用,無論成員的起始字母是什么。例如,如果想要設置textBox1的PrefeereHeight屬性,但記不起來該怎么做,只要鍵入“textBox1.PrefeereHeight”,它就會自動地過濾掉其他的成員,而只留下含“paging”一詞的成員,如圖4-21所示。

圖4-21 搜尋關鍵詞
2.搜尋類型
Visual Studio 2010的這個新的智能提示過濾功能在快速尋找類和類型時也非常有用。例如,當鍵入“List”來聲明一個變量時,編輯器會提供自動的過濾,顯示名稱中含有“List”一詞的所有類型(包括IList<>和SortedList<>,它們的起始字母并不是“List”),如圖4-22所示。這將極大地方便開發人員找到記不全的類型名稱。

圖4-22 搜尋類型
4.4 小結
本章介紹了C#中操作字符串和正則表達式的方法。首先介紹了C#字符串操作;然后結合實例講解了字符串的格式化、字符串的比較、字符串的連接、字符串的復制截取等操作;另外還介紹了正則表達式的基本語法規則,通過實例向讀者展示了正則表達式的用法;最后介紹了C# 4.0的新特性“智能提示的改進”。
4.5 練習
一、填空題
1.Visual C#提供了( )和StringBuilder兩種類來對字符串進行處理。
2.格式化字符串可以用ToString()方法和( )方法來實現。
3.Compare方法比較兩字符串,如果兩字符串相等,則返回的結果值為( )。
4.Equals方法比較兩字符串,如果兩字符串相等,則返回的結果值為( )。
5.Append()方法屬于( )類。
6.截取字符串Substring()方法屬于( )類。
7.分割字符串可以用String類的( )方法來實現。
8.C#中使用正則表達式需要引用命名空間System.Text.( )。
9.正則表達式字符“*” 表示匹配( )個或多個字符。
10.使用正則表達式字符( )可以將匹配模式改成非貪婪。
二、簡答題
1.簡述String和StringBuilder類的異同。
2.什么是正則表達式?。
三、上機題
1.使用C#創建一個控制臺應用程序,獲取當前日期,格式輸出當前月日。
2.給定姓名字符串“張三,李四|王五、趙六”,要求編程取出字符串中的姓名,并輸出顯示。
3.寫一個正則表達式,匹配字符串“<html> test </html>”。
- Spring Boot開發與測試實戰
- Python科學計算(第2版)
- 騰訊iOS測試實踐
- 零基礎學Scratch少兒編程:小學課本中的Scratch創意編程
- Building a RESTful Web Service with Spring
- Learning AWS Lumberyard Game Development
- R語言編程指南
- Python高級編程
- Mastering Ubuntu Server
- Spring快速入門
- Oracle 18c 必須掌握的新特性:管理與實戰
- Learning Probabilistic Graphical Models in R
- 軟件體系結構
- Maven for Eclipse
- SCRATCH編程課:我的游戲我做主