官术网_书友最值得收藏!

4 字符串

ASP.NET可以快速地開發動態網頁,實現復雜的功能,這得益于.NET Framework包含了一個巨大的基礎類庫,利用它,開發者可以通過編寫少量的代碼,快速實現各種應用。

字符串操作是Web應用最重要的操作之一。字符串是頁面和用戶交互的主要方式,用戶在頁面上的信息輸入,頁面對用戶呈現的反饋信息,主要是使用字符串來實現的,鑒于此,本章將首先介紹ASP.NET開發中的字符串相關的操作技術。

4.1 字符串String

【本節示例參考:\示例代碼\C04\Example_String】

System.String是最常用的字符串操作類,用來表示文本,即一系列的Unicode字符,可以幫助開發者完成絕大部分的字符串操作功能。圖4.1給出了String類的常用屬性和方法。

圖4.1 System.String類

下面將從各個應用的角度對String類進行詳細的介紹。

4.1.1 比較字符串

比較字符串是指按照字典排序規則,判定兩個字符串的相對大小。在String類中,常用的比較字符串的方法包括Compare、CompareTo、CompareOrdinal及Equals,下面進行詳細介紹。

說明

字典規則就是在一本英文字典中,出現在前面的單詞小于出現在后面的單詞。

1.使用Compare方法比較

Compare方法是String類的靜態方法,用于全面比較兩個字符串對象,有8種重載方式:

(1)int Compare(string strA, string strB)

(2)int Compare(string strA, string strB, bool ignoreCase)

(3)int Compare(string strA, string strB, StringComparison comparisonType)

(4)int Compare(string strA, string strB, bool ignorCase, CultureInfo culture)

(5)int Compare(string strA, int indexA, string strB, int indexB, int length)

(6)int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignorCase)

(7)int Compare(string strA, int, string strB, int indexA, int length, StringComparison comparisonType)

(8)int Compare(string strA, int, string strB, int indexA, int length, bool ignorCase, CultureInfo culture)

在以上的參數列表中,各參數含義如下:

(1)strA和strB:待比較的兩個字符串。

(2)ignorCase:指定是否考慮大小寫,當取true時忽略大小寫,取false時區分大小寫。

(3)comparisonType:指示比較是應使用當前區域性還是固定區域性,是應考慮還是應忽略比較字的大小寫,是使用字(區分區域性)排序規則還是序號(不區分區域性)排序規則。其取值為StringComparison枚舉,如表4.1所示。

表4.1 StringComparison 枚舉值列表

(4)indexA和indexB:在當需要比較兩個字符串中的子串時,indexA和indexB為strA和strB中子字符串的起始位置。

(5)length:待比較的字符串的最大長度。

(6)culture:字符串的區域性信息,指示字符串的區域性特定信息,如關聯的語言、子語言、國家/地區、日歷和區域性約定。

Compare方法的返回值如表4.2所示。

表4.2 Compare方法的返回值

下例使用Compare方法來比較兩個字符串,其輸出結果如注釋語句所示。為了本節介紹示例時的方便,假設兩個字符串strA=“Hello”,StrB=“World”,下面給出的各個示例代碼中均如此。下面的代碼將實現利用Compare方法進行比較。

代碼4-1 使用Compare比較兩個字符串:Default.aspx.cs

    1.   //定義兩個String對象,并對其賦值,本節下面示例代碼中不再重復給出
    2.   System.String strA="Hello";
    3.   System.String strB="World";
    4.
    5.   //字符串比較
    6.   bool b1=String.Compare(strA,strB);      //-1
    7.   bool b2=String.Compare(strA,strA);      //0
    8.   bool b3=String.Compare(strB,strA);      //1

本例使用了Compare的第(1)個重載方法,對于其余重載方法,讀者可以自行試驗。鑒于內容雷同,此處不再一一給出詳細示例。

說明

String類的另一個比較方法CompareOrdinal同Compare方法非常類似,它比較兩個字符串,但不考慮區域性問題,在此不再贅述。

2.CompareTo方法

CompareTo方法將當前字符串對象與另一個字符串對象作比較,其作用與Compare類似,返回值也相同。不過同Compare相比,其區別在于:

(1)CompareTo不是靜態方法,可以通過一個String對象調用。

(2)CompareTo沒有重載形式,只能按照大小寫敏感方式比較兩個整串。

CompareTo方法的使用如下例所示。

代碼4-2 使用CompareTo比較字符串:Default.aspx.cs

    1.   //CompareTo
    2.   System.String strA="Hello";
    3.   bool b1=strA.CompareTo(strB);         //-1

3.Equals方法

Equals方法用于方便地判斷兩個字符串是否相同,有4種常用的重載形式:

(1)bool Equals(string)

(2)bool Equals(string, StringComparison comparisonType)

(3)static bool Equals(string, string)

(4)static bool Equals(string, string, StringComparison comparisonType)

如果兩個字符串相等,Equals()返回值為true;否則,返回false。Equals方法的使用如下例所示。

代碼4-3 使用Equals比較兩個字符串:Default.aspx.cs

    1.   //Equals
    2.   bool b1=String.Equals(strA,strB);        //false
    3.   bool b2=strA.Equals(strB);             //false

4.比較運算符

String支持兩個比較運算符“= =”和“!=”,分別用于判斷兩個字符串是否相等,并區分大小寫。相對于上面介紹的方法,這兩個運算符使用更加直觀和方便。下例中,使用“==”和“!=”對“Hello”和“World”進行比較。

代碼4-4 使用==和!=比較兩個字符串示例:Default.aspx.cs

    1.   //使用==和!=
    2.   bool b1=(strA==strB);                 //false
    3.   bool b2=(strA!=strB);                 //true

4.1.2 判定首尾字符串

當需要判定一個字符串是否以特定的字符開頭或者結尾的時候,可以用String類的StartsWith/EndsWith。其中,StartsWith方法可以判斷一個字符串對象是否以另一個子字符串開頭,如果是,返回true;否則返回false。其定義為:

public bool StartsWith(string value);

其中,參數value即待判定的子字符串,使用非常簡單,一個示例如下。

代碼4-5 使用StartsWith判斷首字符串示例:Default.aspx.cs

    1.   //StartsWith|EndWith
    2.   bool b1=strA.StartsWith("He");      //true
    3.   bool b2=strA.StartsWith("MM");     //false

另外,EndsWith方法可以判斷一個字符串是否以另一個子字符串結尾,用法和StartsWith相同,不再贅述。

4.1.3 判斷是否包含子串

想要判斷一個字符串中是否包含某個子串,可以用Contains方法來實現:

        public bool Contains (string value)

參數value為待判定的子串。如果包含,返回true;否則返回false。下面的代碼判斷“Hello”中是否包含兩個子串。

代碼4-6 使用Contains判斷是否包含子串:Default.aspx.cs

    1.   bool b1=strA.Contains("ll");             //true
    2.   bool b1=strA.Contains("MM");          //false

4.1.4 定位字符和子串

定位子串是指在一個字符串中尋找其中包含的子串或者某個字符。在String類中,常用的定位子串和字符的方法包括IndexOf/LastIndexOf及IndexOfAny/LastIndexOfAny,下面進行詳細介紹。

1.IndexOf/LastIndexOf

IndexOf方法用于搜索在一個字符串中,某個特定的字符或者子串第一次出現的位置,該方法區分大小寫,并從字符串的首字符開始以0計數。如果字符串中不包含這個字符或子串,則返回-1。常用的重載形式如下所示。

(1)定位字符:

int IndexOf(char value)

int IndexOf(char value, int startIndex)

int IndexOf(char value, int startIndex, int count)

(2)定位子串:

int IndexOf(string value)

int IndexOf(string value, int startIndex)

int IndexOf(string value, int startIndex, int count)

在上述重載形式中,其參數含義如下:

○ value:待定位的字符或者子串。

○ startIndex:在總串中開始搜索的位置。

○ count:在總串中從起始位置開始搜索的字符數。

下面的代碼在“Hello”中尋找字符‘l’第一次出現的位置。

代碼4-7 使用IndexOf尋找字符第一次出現位置:Default.aspx.cs

    1.   String s=”Hello”;
    2.   int I=s.IndexOf(‘l’));      //2

與IndexOf類似,LastIndexOf用于搜索在一個字符串中,某個特定的字符或者子串最后一次出現的位置,其方法定義和返回值都與IndexOf相同,不再贅述。

2.IndexOfAny/LastIndexOfAny

IndexOfAny方法功能同IndexOf類似,區別在于,它可以搜索在一個字符串中,出現在一個字符數組中的任意字符第一次出現的位置。同樣,該方法區分大小寫,并從字符串的首字符開始以0計數。如果字符串中不包含這個字符或子串,則返回-1。常用的IndexOfAny重載形式有3種:

(1)int IndexOfAny(char[]anyOf);

(2)int IndexOfAny(char[]anyOf, int startIndex);

(3)int IndexOfAny(char[]anyOf, int startIndex, int count)。

在上述重載形式中,其參數含義如下:

(1)anyOf:待定位的字符數組,方法將返回這個數組中任意一個字符第一次出現的位置。

(2)startIndex:在原字符串中開始搜索的位置。

(3)count:在原字符串中從起始位置開始搜索的字符數。

下例在“Hello”中尋找字符‘l’第一次和最后一次出現的位置。

代碼4-8 使用IndexOfAny尋找子串第一次和最后一次出現位置:Default.aspx.cs

    1.   String s=“Hello”;
    2.   char[]anyOf={'H','e','l'};
    3.   int i1=s.IndexOfAny(anyOf));           //0
    4.   int i2=s.LastIndexOfAny(anyOf));        //3

同IndexOfAny類似,LastIndexOfAny用于搜索在一個字符串中,出現在一個字符數組中任意字符最后一次出現的位置。

4.1.5 格式化字符串

Format方法用于創建格式化的字符串及連接多個字符串對象。如果讀者熟悉C語言中的sprintf()方法,可以了解兩者有類似之處。Format方法也有多個重載形式,最常用的是:

        static string Format(string format, params object[] args);

其中,參數format用于指定返回字符串的格式,而args為一系列變量參數。可以通過下面的實例來掌握其使用方法。

代碼4-9 使用Format設置字符串格式:Default.aspx.cs

    1.   //Format
    2.   String newStr=String.Format("{0},{1}!",strA,strB);  //Hello,World!

在format參數中包含一些用大括號擴起來的數字,如{0}、{1},這些數字分別一一對應于args參數數組中的變量。在生成結果字符串時,將使用這些變量代替{i}。需要說明的是,這些變量并不要求必須為String類型。

在特定的應用中,Format方法非常方便。例如,想要輸出一定格式的時間字符串,便可以使用Format方法,如下面代碼所示:

    newStr=String.Format("CurrentTime={0:yyyy-MM-dd}",System.DateTime.Now);//形如:2007-05-19

其中,格式字符串“yyyy-MM-dd”指定返回時間的格式如“2007-05-19”,其定義可參考System.Globalization.DateTimeFormatInfo類。

4.1.6 連接字符串

String類包含了兩個連接字符串的靜態方法,它們是Concat和Join,下面分別進行介紹。

1.Concat方法

Concat方法用于連接兩個或多個字符串。如果讀者熟悉C語言中的strcat()方法,可以了解兩者有類似之處。Concat方法也有多個重載形式,最常用的是:

        static string Concat(params string[]values);

其中,參數values用于指定所要連接的多個字符串,可以通過下面的實例來掌握其使用方法。

代碼4-10 使用Concat連接字符串:Default.aspx.cs

    1.   //Concat
    2.   newStr="";
    3.   newStr=String.Concat(strA,"",strB);
    4.   Console.WriteLine(newStr);     //"Hello World"

2.Join方法

Join方法利用一個字符數組和一個分隔符構造新的字符串。它常常用于把多個字符串連接在一起,并用一個特殊的符號來分隔開。Join的常用形式為:

static string Join(string separator, string[]value);

其中,參數separator為指定的分隔符,而values用于指定所要連接的多個字符串數組,下例用“^^”分隔符把“Hello”和“World”連起來。

代碼4-11 使用Join連接字符串:Default.aspx.cs

    1.   //Join
    2.   newStr="";
    3.   String[]strArr={strA,strB};
    4.   newStr=String.Join("^^",strArr);
    5.   Console.WriteLine(newStr);     //"Hello^^World"

3.連接運算符“+”

String支持連接運算符“+”,可以方便地連接多個字符串,如下例把“Hello”和“World”連接起來。

代碼4-12 使用“+”連接字符串:Default.aspx.cs

    1.   //使用+
    2.   newStr="";
    3.   newStr=strA+strB;       //"HelloWorld"

4.1.7 拆分字符串

使用Join方法,可以利用一個分隔符把多個字符串連接起來。反過來,使用Split方法可以把一個整串,按照某個分隔字符或者字符串,拆分成一系列小的字符串。例如,把整串“Hello^^World”按照字符“^”進行拆分,可以得到3個小的字符串:“Hello”、“”(空串)和“World”;根據字符串“^^”,則可以得到兩個小的字符串:“Hello”和“World”。

1.根據字符拆分

根據字符拆分的Split重載方法是:

        public string[]Split(params char[]separator);

其中,參數separator數組包含分隔符。下例把“Hello^^World”根據“^”進行拆分。

代碼4-13 根據字符分裂分隔符字符串:Default.aspx.cs

    1.   //Split
    2.   newStr="Hello^^World";
    3.   char[]separator={'^'};
    4.   String[]splitStrings=new String[100];
    5.   splitStrings=newStr.Split(separator);
    6.   int i=0;
    7.   while(i<splitStrings.Length)
    8.   {
    9.       Console.WriteLine(splitStrings[i])
    10.      i++;
    11.  }

輸出結果為:

    Hello
    World

2.根據字符串拆分

根據字符拆分的Split重載方法是:public string[]Split(string[] separator,StringSplitOptions options)。

其中,參數separator數組是分隔字符串數組;參數options取值RemoveEmptyEntries時,將過濾空的數組元素,若取值one則返回。下例把“Hello^^World”根據“^^”進行拆分。

代碼4-14 根據字符串分裂分隔符字符串:Default.aspx.cs

    1.   //split
    2.   String[]separator=new string[]{strB.Text};
    3.   String[]splitStrings=new String[100];
    4.   splitStrings=newStr.Split(separator,StringSplitOptions.None);
    5.   int i=0;
    6.   while(i<splitStrings.Length)
    7.   {
    8.       Page.Response.Write(splitStrings[i]+"<br/>");
    9.       i++;
    10.  }

輸出結果為:

    Hello
    World

4.1.8 插入字符串

String類包含了在一個字符串中插入新元素的方法Insert,用于在字符串的任意位置插入任意的字符:

○ public string Insert(int startIndex, string value);

其中,參數startIndex用于指定所要插入的位置,從0開始索引;value指定所要插入的字符串。下例中,在“Hello”的字符“H”后面插入“World”,構造一個串“HWorldello”。

代碼4-15 使用Insert插入字符串:Default.aspx.cs

    1.   //Insert
    2.   newStr="";
    3.   newStr=strA.Insert(1,strB); //"HWorldello"

4.1.9 填充字符串

有時候,可能需要對一個字符串進行填充,例如,想要把“Hello”變為長度為20個字符的串,并使用字符“*”進行填充,即變為“***************Hello”。PadLeft方法可以實現這個功能,用于在一個字符串的左側進行字符填充,使其達到一定的長度。PadLeft有兩種重載形式:

○ public string PadLeft(int totalWidth);

○ public string PadLeft(int totalWidth, char paddingChar);

其中,參數totalWidth指定了填充后的字符長度,而paddingChar指定所要填充的字符,如果默認,則填充空格符號。

下例中,實現了對“Hello”的填充操作,使其長度變為20。

代碼4-16 使用PadLeft填充字符串:Default.aspx.cs

    1.   //PadLeft
    2.   newStr="";
    3.   newStr=strA.PadLeft(20,'*');    //"***************Hello"

與PadLeft類似,PadRight可以實現對一個字符在其右側的填充功能,對其不作贅述。

4.1.10 刪除字符串

String類包含了刪除一個字符串的方法,可以用Remove方法在任意位置刪除任意長度的字符串,也可以使用Trim/TrimEnd/TrimStart方法剪切掉字符串中的一些特定字符。

1.Remove方法

Remove方法從一個字符串的制定位置開始,刪除指定數量的字符。最常用的為:

        public string Remove( int startIndex, int count);

其中,參數startIndex用于指定所要開始刪除的位置,從0開始索引;count指定所要刪除的字符數量。下例中,把“Hello”中的“ell”刪掉。

代碼4-17 使用Remove刪除字符串:Default.aspx.cs

    1.   //Remove
    2.   newStr="";
    3.   newStr=strA.Remove(1,3);     //"Ho"

2.Trim/TrimStart/TrimEnd方法

若想把一個字符串首尾處的一些特殊字符剪切掉,如去掉一個字符串首尾的空格等,可以使用String的Trim方法。其形式為:

○ public string Trim ();

○ public string Trim (params char[]trimChars);

其中,參數trimChars數組包含了指定所要去掉的字符,如果默認,則刪除空格符號。下例中,實現了對“@Hello# $”的凈化,去掉首尾的特殊符號。

代碼4-18 使用Trim去掉首尾的特殊符號:Default.aspx.cs

    1.   //Trim
    2.   newStr="";
    3.   char[]trimChars={'@','#','$',''};
    4.   String strC="@Hello#$";
    5.   newStr=strC.Trim(trimChars);   //"Hello"

另外,與Trim類似,TrimStart和TrimEnd分別剪切掉一個字符串開頭和結尾處的特殊字符。

4.1.11 復制字符串

String類包含了復制字符串方法Copy和CopyTo,可以完成對一個字符串及其一部分的復制操作。

1.Copy方法

若想把一個字符串復制到另一個字符串中,可以使用String的靜態方法Copy來實現,其形式為:

static string Copy(string str);

其中,參數str為需要復制的源字符串,返回目標字符串。下例中,把TextBoxA中的字符串復制到newStr中。

代碼4-19 使用Copy復制字符串:Default.aspx.cs

    1.   //Copy
    2.   newStr="";
    3.   newStr=String.Copy(strA);      //"Hello"

2.CopyTo方法

CopyTo方法可以實現Copy同樣的功能,但功能更為豐富,可以復制源字符串中的一部分到一個字符數組中。另外,CopyTo不是靜態方法,其形式為:

        public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count);

其中,參數sourceIndex為需要復制的字符起始位置,destination為目標字符數組,destinationIndex制定目標數組中的開始存放位置,而count指定所要復制的字符個數。下例中,把strA字符串“Hello”中的“ell”復制到newCharArr中,并在newCharArr中從第2個元素開始存放。

代碼4-20 使用CopyTo復制字符串:Default.aspx.cs

    1.   //CopyTo
    2.   char[]newCharArr=new char[100];
    3.   strA.CopyTo(2,newCharArr,0,3); //"Hel"

4.1.12 替換字符串

如果想要替換掉一個字符串中的某些特定字符或者某個子串,可以使用Replace方法來實現,其形式為:

○ public string Replace(char oldChar, char newChar);

○ public string Replace(string oldValue, string newValue);

其中,參數oldChar和oldValue為待替換的字符和子串,而newChar和newValue為替換后的新字符和新子串。下例把“Hello”通過替換變為“Hero”。

代碼4-21 使用Replace替換字符串:Default.aspx.cs

    1.   //Replace
    2.   newStr=strA.Replace("ll","r");            //Hero

4.1.13 更改大小寫

String提供了方便轉換字符串中所有字符大小寫的方法ToUpper和ToLower。這兩個方法沒有輸入參數,使用也非常簡單。下例首先把“Hello”轉換為“HELLO”,然后再變為小寫形式“hello”。

代碼4-22 使用ToUpper更改字符串大小寫:Default.aspx.cs

    1.   //ToUpper
    2.   newStr=strA.ToUpper();            //HELLO
    3.   //ToLower
    4.   newStr=strA.ToLower();            //hello

4.2 動態串StringBuilder

【本節示例參考:\示例代碼\C04\Example_StringBuilder】

上一節介紹了String類,除此之外,還有一個常用的字符串操作對象StringBuilder,其常用的屬性和方法如圖4.2所示。

StringBuilder類位于命名空間System.Text中,在使用它時,可以在文件頭通過using語句引入該空間:

    using System.Text;

聲明StringBuilder對象需要使用new關鍵字,并可以對其進行初始化。如下語句聲明了一個StringBuilder對象myStringBuilder,并初始化為“Hello”:

    StringBuilder myStringBuilder=new StringBuilder("Hello");

如果不使用using關鍵字在文件頭引入System.Text命名空間,也可以通過空間限定來聲明StringBuilder對象:

    System.Text.StringBuilder myStringBuilder=new StringBuilder("Hello");

在聲明時,也可以不給初始值,然后通過其他方法進行賦值。

圖4.2 StringBuilder類

4.2.1 比較String

通過上面的介紹,可以看出StringBuilder與String在許多操作上(如Insert、Remove、Replace)是非常相似的,兩者的區別在于:

(1)String為靜態串,一旦定義一個String對象,它是不可改變的。在使用其方法(如插入、刪除操作)時,都要在內存中創建一個新的String對象,而不是在原對象的基礎上進行修改,這就需要開辟新的內存空間。

(2)與String類相比,System.Text.StringBuilder類可以實現動態字符串。此處,動態的含義是指在修改字符串時,系統不需要創建新的對象,不會重復開辟新的內存空間,而是直接在原StringBuilder對象的基礎上進行修改。

(3)在操作性能和內存效率方面,StringBuilder要比String好得多,可以避免產生太多的臨時字符串對象,特別是對于經常重復進行修改的情況更是如此。而另一方面,String類提供了更多的方法,可以使開發者更快地實現應用。

在兩者的選擇上,如果應用對系統性能、內存要求比較嚴格,以及經常處理大規模的字符串,推薦使用StringBuilder對象;否則,可以選擇使用String。

4.2.2 設置容量

StringBuilder對象為動態字符串,可以對其設置好的字符數量進行擴充。另外,還可以設置一個最大長度,這個最大長度稱為該StringBuilder對象的容量(Capacity)。

為StringBuilder設置容量的意義在于,當修改StringBuilder字符串時,當其實際字符長度(即字符串已有的字符數量)未達到其容量之前,StringBuilder不會重新分配空間;當達到容量時,StringBuilder會在原空間的基礎之上,自動分配新的空間,并且容量翻倍。如果不進行設置,StringBuilder默認初始分配16個字符長度。

有兩種方式來設置一個StringBuilder對象的容量。

1.使用構造函數

StringBuilder構造函數可以接收容量參數,例如,下面語句聲明一個StringBuilder對象sb2,并設置其容量為100。

    //使用構造函數設置容量
    StringBuilder sb2=new StringBuilder("Hello",100);

2.使用Capacity讀/寫屬性

Capacity屬性指定StringBuilder對象的容量,例如下面語句首先聲明一個StringBuilder對象sb3,然后利用Capacity屬性設置其容量為100。

    //使用Capacity屬性設置容量
    StringBuilder sb3=new StringBuilder("Hello");
    sb3.Capacity=100;

4.2.3 追加字符串

追加一個StringBuilder是指將新的字符串添加到當前StringBuilder字符串的結尾處,可以使用Append和AppendFormat來實現這個功能。

1.Append方法

Append方法實現簡單的追加功能,其常用形式為:

○ public StringBuilder Append(object value);

其中,參數value既可以是字符串類型,也可以是其他的數據類型,如bool、byte、int等。下例中,把一個StringBuilder字符串“Hello”追加為“Hello World!”。

代碼4-23 使用Append追加字符串:Default.aspx.cs

    1.   //Append
    2.   StringBuilder sb4=new StringBuilder("Hello");
    3.   sb4.Append("World!");    //"Hello World!"

2.AppendFormat方法

AppendFoamat可以實現對追加部分字符串的格式化,可以定義變量的格式,并將格式化后的字符串追加在StringBuilder后面。其常用形式為:

○ StringBuilder AppendFormat(string format, params object[] args);

其中,args數組指定所要追加的多個變量。format參數包含格式規范的字符串,其中包括一系列用大括號括起來的格式字符,如{0:u}。這里,0代表其對應args參數數組中的第0個變量,而“u”定義其格式。下例中,把一個StringBuilder字符串“Today is”追加為“Today is \*當前日期*\”。

代碼4-24 使用AppendFormat追加特定格式的字符串:Default.aspx.cs

    1.   //AppendFormat
    2.   StringBuilder sb5=new StringBuilder("Today is");
    3.   sb5.AppendFormat("{0:yyyy-MM-dd}",System.DateTime.Now);//形如:"Today is 2006-05-20"

4.2.4 插入字符串

StringBuilder的插入操作是指將新的字符串插入到當前StringBuilder字符串的指定位置,如“Hello”變為“Heeeello”,就需要使用插入操作。可以使用StringBuilder類的Insert方法來實現這個功能,其常用形式為:

○ public StringBuilder Insert(int index,object value);

其中,參數index指定所要插入的位置,并從0開始索引,如index=1,則會在原字符串的第2個字符之前進行插入操作;同Append一樣,參數value并不僅可取字符串類型。下例中,把一個StringBuilder字符串“Hello”通過插入操作修改為“Heeeello”。

代碼4-25 使用Insert插入字符串:Default.aspx.cs

    1.   //Insert
    2.   StringBuilder sb6=new StringBuilder("Hello");
    3.   sb6.Insert(2,"eee");           //在”He”后面插入,變為"Heeeello!"

4.2.5 刪除字符串

StringBuilder的刪除操作可以從當前StringBuilder字符串的指定位置,刪除一定數量的字符。例如,把“Heeeello”變為“Hello”,就需要使用刪除操作。可以使用StringBuilder類的Remove方法來實現這個功能,其常用形式為:

○ public StringBuilder Remove( int startIndex, int length);

其中,參數startIndex指定所要刪除的起始位置,其含義同Insert中的index相同;length參數指定所要刪除的字符數量。下例中,把一個StringBuilder字符串“Heeeello”通過刪除操作修改為“Hello”。

代碼4-26 使用Remove刪除字符串:Default.aspx.cs

    1.   //Remove
    2.   StringBuilder sb7=new StringBuilder("Heeeello");
    3.   Sb3.Remove(2,3);            //在”He”后面刪除3個字符,變為"Hello!"

4.2.6 替換字符串

StringBuilder使用Replace方法來實現替換操作,如想把“Hello”變為“Hero”,就需要使用替換操作,將“ll”替換為“r”。這同String類的Replace方法非常類似,其常用形式包括:

○ public StringBuilder Replace(char oldChar, char newChar);

○ public StringBuilder Replace(string oldValue, string newValue);

其中,參數oldChar和oldValue為待替換的字符和子串,而newChar和newValue為替換后的新的字符和新的子串。下例把“Hello”通過替換變為“Hero”。

代碼4-27 使用Replace替換字符串:Default.aspx.cs

    1.   //Replace
    2.   StringBuilder sb8=new StringBuilder("Hello");
    3.   sb8=sb8.Replace("ll","r");           //Hero

4.3 正則表達式Regex

正則表達式是一個非常大的題目,許多的編程語言和工具都支持正則表達式,.NET類庫空間System.Text.RegularExpressions包括了一系列可以充分發揮正則表達式的類,如圖4.3所示。

本節,將首先介紹正則表達式的含義,并給出構造正則表達式的技術,然后簡單介紹使用Regex類來實現字符串的模式匹配。

圖4.3 System.Text.RegularExpression命名空間

4.3.1 正則表達式簡介

正則表達式是一種可以用于模式匹配的工具。簡單地說,正則表達式就是一套規則,用于去判定其他的元素是否符合它。

例如,在一個用戶注冊頁面中(例如論壇或者交友網站的注冊頁面),可能有“電子郵件”這一項需要用戶填寫。Web系統需要判定用戶所填寫的電子郵件地址是否合法,即是否符合電子郵件地址的規則。眾所周知,電子郵件的格式如下:

    zhangsan@sina.com

可以抽象為下面的規則:

    非空字符序列+’@’+非空字符序列+’.’+com|cn|net

可以稱這樣的一個規則為正則表達式,它可以作為一個模式,去檢驗一個字符串是否滿足規則。

4.3.2 構造正則表達式

正則表達式的本質是使用一系列特殊字符模式,來表示某一類字符串,如上一節示例中的正則表達式“[a-zA-Z]+@[a-zA-Z]+\.com$”,其中:

(1)“[a-zA-Z]+”指包含1個或多個大小寫英文字母的字符串。

(2)“com$”指以“com”結尾的字符串。

(3)“\.”使用轉義字符“\”來表示一個普通的字符“.”,因為“.”在正則表達式中也具有特殊的作用;注意在使用轉義字符“\”時,需要在字符串前加上“@”符號。

綜上所述,“[a-zA-Z]+@[a-zA-Z]+\.com$”可以匹配:非空字符串+“@”+非空字符串+以“.com”結尾的字符串。因此,想要構造正則表達式,必須掌握這些特殊的表達形式,如表4.3所示給出了C#中常用的符號模式。

表4.3 C#正則表達式符號模式

下面給出一些常用的正則表達式,這些都利用了表4.3構造正則表達式的技術。

(1)“^The”:匹配所有以“The”開始的字符串,如“There” 、“Thecat”等。

(2)“he$”:匹配所有以“he”結尾的字符串,如“he”、“she”等。

(3)“ab*”:匹配有一個a后面跟著零個或若干個b的字符串,如“a”、“ab”、“abbb”,……

(4)“ab+”:匹配有一個a后面跟著至少一個或者更多個b的字符串,如“ab”、“abbb”……

(5)“ab?”:匹配有一個a后面跟著零個或者一個b的字符串,包括“a”、“ab”。

(6)“a?b+$”:匹配在字符串的末尾有零個或一個a跟著一個或幾個b的字符串。

(7)“ab{2}”:匹配有一個a跟著2個b的字符串,即“abb”。

(8)“ab{2,}”:匹配有一個a跟著至少2個b的字符串,如“abb” 、“abbb”。

(9)“ab{3,5}”:匹配有一個a跟著3~5個b的字符串,如“abbb” 、“abbbb”。

(10)“hi|hello”:匹配包含“hi”或者“hello”的字符串。

(11)“(b|cd)ef”:表示“bef”或“cdef”。

(12)“a.[0-9]”:匹配有一個a后面跟著一個任意字符和一個數字的字符串。

(13)“^.{3}$”:匹配有任意三個字符的字符串。

(14)“[ab]”:表示一個字符串有一個a或b,相當于“a|b”。

(15)“[a-d]”:表示一個字符串包含小寫的a~d中的一個,相當于“a|b|c|d”或者“[abcd]”。

(16)“^[a-zA-Z]”:表示一個以字母開頭的字符串。

(17)“[0-9]%”:表示一個百分號前有一位的數字。

(18)“,[a-zA-Z0-9]$”:表示一個字符串以一個逗號后面跟著一個字母或數字結束。

4.3.3 使用Regex類

【本節示例參考:\示例代碼\C04\ Example_Match】

Regex類包含若干靜態方法,用于使用正則表達式進行字符串匹配,其常用屬性和方法如圖4.4所示。

圖4.4 Regex類圖

最常用的方法為Match,它在輸入字符串參數中搜索正則表達式的匹配項,并將匹配成功的結果作為單個Match對象返回。其常用形式為:

        static Match Match( string input, string pattern);

其中,方法的參數pattern為一個正則表達式,而input為待匹配的字符串。方法返回一個Match對象。Match對象可以表示單個正則表達式匹配的結果,結合下面具體的示例,對其進行簡單介紹。

下面是一個使用Regex的Match方法進行正則表達式匹配的示例,用一個正則表達式來驗證一個字符串是否是一個合法的電子郵件地址。

代碼4-28 利用Regex驗證E-mail地址:Default.aspx.cs

    1.   public void test()
    2.   {
    3.       string input="zhangsan@sina.com";          //待匹配的輸入串
    4.       string pattern=@"[a-zA-Z]+@[a-zA-Z]+\.com$";  //正則表達式
    5.
    6.       Regex r=new Regex(pattern);                   //聲明一個Regex對象
    7.       Match m=r.Match(input);                       //使用Match方法進行匹配
    8.       if(m.Success)                                //循環輸出所有的匹配子串
    9.       {
    10.          Page.Response.Write(m.Value);
    11.      }
    12.      else
    13.      {
    14.          Page.Response.Write("Invalid Email Address!");
    15.      }
    16.  }

代碼第4行定義了一個正則表達式“[a-zA-Z]+@[a-zA-Z]+\.com$”,其規則為:非空字符串+“@”+非空字符串+“.com”,其具體的含義將在下一節討論。

第6行聲明了一個Regex對象,并通過構造函數為其設置正則表達式;第7行使用Match函數對input字符串進行正則匹配,并將匹配成功的結果串放入一個Match對象。

第8行使用Match對象的Success屬性來判斷是否匹配成功。如果成功,則輸出匹配串,否則,輸出錯誤提示信息。

可以看出,使用Regex類進行字符串的模式匹配非常簡單,真正的難點在于正則表達式的構造。

4.4 字符編碼

【本節示例參考:\示例代碼\C04\Example_Encoding】

ASP.NET中的字符串是Unicode編碼類型的,對于漢字和英文的操作是相同的。另外,還可以使用System.Text命名空間中的類來對字符串進行編碼和解碼。System.Text命名空間中的類如圖4.5所示。

圖4.5 System.Text命名空間

下面,首先介紹字符串編碼的基本知識,然后討論如何使用System.Text中的各個類實現字符串編碼操作。

4.4.1 字符編碼概述

計算機是0和1的世界,只能表達數字。那么為了在計算機中表示字符,就必須進行編碼,如可以指定用65來代表字符“A”。在計算機發展史上,字符編碼的標準經歷了多個時代,如圖4.6所示。

圖4.6 字符編碼標準發展軌跡

下面對這幾種編碼簡單介紹如下。

1.ASCII編碼

在計算機剛剛誕生時,開發者制定ASCII編碼。ASCII碼由一個字節中的7位表示,范圍是0~127,可以表示128個不同的字符,包括英文字母(如ABC、abc)、數字(如123)、常用符號(如~!@),以及特殊符號(如回車)等。在當時,開發者認為這128個字符就足夠滿足所有的字符應用了。

2.擴展ASCII編碼

但時隔不久,開發者們突然發現,在排版中常用的“制表符”沒有出現在這128個字符中,只能對ASCII碼進行擴展,使用一個字節的全部8位來表示字符,這稱為擴展ASCII碼,范圍是0~255共256個字符,能表示256個不同的字符。

3.多字節字符集

擴展ASCII碼在表達西方語言體系的時候是夠用了,但是對于表達東方的方塊字時,卻出現了問題,這是因為方塊字并不是由字母排列組合而成的,僅僅定義一百多個字母就試圖表達所有的方塊字行不通。

為了解決漢字的編碼表示,中國利用連續2個擴展ASCII碼的擴展區域(即160以后)來表示一個漢字,該編碼標準為GB-2312。后來,日文、韓文、阿拉伯文、臺灣繁體(BIG-5)等方塊語言地區都使用類似的方法擴展了本地字符集的定義,統一稱為多字節字符集(MBCS)。

4.Unicode編碼

多字節字符集解決了表達方塊字的問題,但這是有缺陷的,因為各個國家地區定義的字符集有沖突。例如,使用GB-2312的軟件,在BIG-5的環境下就會顯示亂碼,反之亦然。為了解決這個沖突,出現了Unicode標準字符集。Unicode使用2個字節表示一個字符,共6萬多個字符,包括英文字母和方塊字。

4.4.2 字符編碼類

ASP.NET中的字符采用Unicode編碼標準,但是,有時候也需要同其他編碼標準的程序進行字符數據交互,如調用使用ASCII編碼、C++實現的COM組件等。為了在各種編碼標準的字符間實現轉換,.NET提供了幾個字符編碼類,如表4.4所示。

表4.4 System.Text空間中的編碼/解碼相關類

由于各個類的使用非常類似,在此只對Encoding類進行介紹,其類屬性和方法如圖4.7所示。

圖4.7 Encoding類

此處的屬性介紹如下:

(1)ASCII:獲取ASCII(7位)字符集的編碼對象。

(2)Unicode:獲取Unicode格式的編碼對象。

(3)UTF7:獲取UTF-7格式的編碼對象。

(4)UTF8:獲取UTF-8格式的編碼對象。

(5)EncodingName:獲取編碼的可讀說明。

常用的方法簡介如下:

(1)Covert:將字節數組從一種編碼轉換為另一種。

(2)GetBytes:將指定的String或字符數組的全部或部分內容編碼為字節數組。

(3)GetString:將指定字節數組解碼為字符串。

下面通過一個示例來說明其應用,示例將使用Encoding類,顯示Unicode字符串“M國”的各種編碼形式。

代碼4-29 顯示編碼形式:Default.aspx.cs

    1.   public void test()
    2.   {
    3.      String str="M國";    //C#默認Unicode編碼格式
    4.
    5.      //Unicode編碼
    6.      Encoding uni_str=Encoding.Unicode;
    7.      //獲取Unicode編碼
    8.      byte[]uni_byte=uni_str.GetBytes(str);
    9.      Page.Response.Write("Unicode:");
    10.     for(int i=0;i<uni_byte.Length;i++)
    11.     {
    12.         Page.Response.Write(uni_byte[i]+"-");
    13.     }
    14.     //獲取Unicode編碼格式字符串
    15.     Page.Response.Write(">"+uni_str.GetString(uni_byte)+"<br/>");   //輸出:"M國"
    16.
    17.     //ASCII編碼
    18.     Encoding ascii_str=Encoding.ASCII;
    19.     //獲取ASCII編碼
    20.     byte[]ascii_byte=ascii_str.GetBytes(str);
    21.     Page.Response.Write("ASCII:");
    22.     for(int i=0;i<ascii_byte.Length;i++)
    23.     {
    24.         Page.Response.Write(ascii_byte[i]+"-");
    25.     }
    26.     //獲取ASCII編碼格式字符串
    27.     Page.Response.Write(">"+ascii_str.GetString(ascii_byte)+"<br/>");//輸出:"M?"
    28.   }

第3行,示例首先定義了一個Unicode字符串“M國”,注意.NET默認的編碼標準為Unicode。

首先,示例顯示“M國”的Unicode編碼。第6行聲明了一個Unicode編碼對象,然后在第8行使用了GetBytes方法得到“M國”的Unicode編碼。第10~13輸出這個編碼,應該如下所示:

    Unicode:77-0-253-86

其中,77-0為字符“M”的Unicode編碼,而253-86為字符“國”的Unicode編碼。可以看出,Unicode使用兩個字節表示一個中文或英文字符。

第15行使用GetString方法顯示Unicode編碼的字符串,輸出為“M國”。

然后,示例顯示“M國”的Unicode編碼。第18行聲明了一個ASCII編碼對象,然后在第20行使用了GetBytes方法得到“M國”的ASCII編碼。第22~25行輸出這個編碼,如下所示:

    ASCII:77-63

其中,77為字符“M”的ASCII編碼,而“63”為字符“國”的ASCII編碼。

第27行使用GetString方法顯示ASCII編碼的字符串,輸出為“M?”。很明顯,可以看出,ASCII試圖使用一個字節表示一個字符。對于英文字符而言,沒有任何影響。但是對于中文字符,就會丟失一定的信息,無法正常顯示。示例運行結果如圖4.8所示。

圖4.8 字符串編碼示例運行結果

承上啟下

■ 學完本章后,讀者需要回答:

1.能否使用String對象實現字符串的以下操作。

(1)比較:Compare

(2)判定首位:StartsWith|EndsWith

(3)判定子串:Contains

(4)定位子串:IndexOf|IndexOfAny|LastIndexOf|LastIndexOfAny

(5)格式化:Format

(6)連接:Concat|Join

(7)分裂:Split

(8)插入:Insert

(9)填充:PadLeft|PadRight

(10)刪除:Remove|Trim/TrimStart/TrimEnd

(11)復制:Copy|CopyTo

(12)替換:Replace

(13)大小寫轉換:ToUpper|ToLower

2.為什么稱StringBuilder對象為動態字符串?它和String對象有何不同之處?

3.如何使用StringBuilder對象完成字符串的以下操作。

(1)設置字符串最大長度:Capacity

(2)追加字符串:Append|AppendFormat

(3)插入字符串:Insert

(4)刪除字符串:Remove

(5)替換字符串:Replace

4.什么是正則表達式?是否能夠構造匹配URL字符串的正則表達式?

5.如何使用Regex類操作正則表達式?

6.歷史上曾經有哪些字符編碼標準?.NET中如何實現編碼的轉換?

■ 在下一章中,讀者將會了解:

1.數組的概念。

2.使用數組完成以下操作。

(1)元素訪問:GetValue

(2)轉化類型:ConvertAll

(3)遍歷數組:foreach

(4)排序數組:Sort

(5)查找元素:BinarySearch/Contains

(6)反轉數組:Reverse

(7)復制數組:Copy/CopyTo

3.C#中的集合命名空間包含的常用類,如ArrayList、Queue、Stack等。

4.使用ArrayList類完成以下操作。

(1)添加元素:Add/AddRange

(2)插入元素:Insert/InsertRange

(3)刪除元素:Remove/RemoveAt/RemoveRange

(4)排序元素:Sort

(5)查找元素:BinarySeach

5.利用Queue類和Stack類來實現隊列及堆棧的以下操作。

(1)入隊:Enqueue

(2)出隊:Dequeue

(3)入棧:Push

(4)出棧:Pop

主站蜘蛛池模板: 杭锦后旗| 集贤县| 丰县| 察隅县| 高唐县| 垦利县| 威远县| 无锡市| 运城市| 三河市| 农安县| 敖汉旗| 海门市| 青神县| 商河县| 长乐市| 黄冈市| 丰镇市| 宁国市| 太康县| 石泉县| 东乡族自治县| 岑巩县| 永昌县| 昌都县| 赤峰市| 海阳市| 胶南市| 桓仁| 中西区| 汝城县| 大城县| 交口县| 晋城| 京山县| 芒康县| 仙桃市| 留坝县| 任丘市| 漳平市| 介休市|