1. 程式人生 > >C#中string型別的常用方法總結

C#中string型別的常用方法總結

在C#語言中,字串是System.String類的一個引用型別,但與其他引用型別不同的是,C#將字串視為一個基本型別,它可以申請為一個常量,也可以直接給它賦值。由於C#中的字串是由System.String類派生而來的引用物件,因此可以使用String類的方法來對字串進行各種操作。下面通過幾個例子來講述String類的幾個重要方法以及字串拘留池機構。

1、字串的複製:
(1)、String.Copy(str):引數str為要複製的字串,它回返回一個與該字串相等的字串
(2)、SreStr.CopyTo(StartOfSreStr, DestStr, StartOfDestStr, CopyLen):它必須被要複製的字串例項呼叫,它可以實現複製其中某一部分到目標字串的指定位置

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string SourceStr = "hello everyOne!!";
            string CopyStr = String.Copy(SourceStr);
            char[] CopyToStr = new char[20];
            SourceStr.CopyTo(6, CopyToStr, 0, 10);  //該函式必須有一個例項呼叫,並且第二個引數為字串陣列
Console.WriteLine("CopyStr = " + CopyStr); Console.Write("CopyToStr = "); Console.WriteLine(CopyToStr); } } } 結果:CopyStr = hello everyOne!! CopyToStr = everyOne!!

Copy()方法只適用於需要吧某個字串完整複製到另一個字串中的情況,相比之下CopyTo()則比較靈活。

2、字串的比較:
String類字串比較大概有4種方法:Compare(),CompareTo(), CompareOrdinal()和Equals(). Compare()方法是CompareTo()的靜態版本.而Equals()與”==”是等價的,只要使用”==”運算子,就會呼叫Equals()方法。CompareOrdinal()對兩個字串進行比較,不考慮本地化語言和文化。

(1)、String.Compara(str1, str2):
(2)、String.CompareTo(string value):該例項與value的值進行比較。返回:如果string大於value則返回1,如果string小於value則返回-1,如果兩個相等則返回0。
(3)、String.CompareOrdinal(str1, str2):是將整個字串每5個字元(10個位元組)分成一組,然後逐個比較,找到第一個不相同的ASCII碼後退出迴圈。並且求出兩者的ASCII碼的差。【我不明白為什麼要實現的如此麻煩。但是在CLR via C#上有這樣的話:這個方法比其他方法都要快。應該是有一定道理的吧。所以當我們比較大小的時候,儘量使用CompareOrdinal方法。】
(4)、String.Equals(string value):用於比較兩個字串是否相等。返回:如果和String相等則為true;否則為false。【由於是非安全程式碼的比較,所以效率要比我們用安全程式碼高得多】

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int nResult = 0;
            bool bResult = false;

            string str1 = "you are very happy!!";
            string str2 = "I am very happy!!";
            string str3 = "I am very happy!!";
            nResult = string.Compare(str1, str2);
            Console.WriteLine("Compare(str1, str2) = " + nResult);
            nResult = str1.CompareTo(str2);
            Console.WriteLine("str1.CompareTo(str2) = " + nResult);
            nResult = string.CompareOrdinal(str1, str2);
            Console.WriteLine("CompareOrdinal(str1, str2) = " + nResult);
            bResult = str2.Equals(str3);
            Console.WriteLine("str2.Equals(str3) = " + bResult);
            Console.WriteLine("str2 == str3   " + (str2 == str3 ? true : false));
        }
    }
}
結果:Compare(str1, str2) = 1
     str1.CompareTo(str2) = 1
     CompareOrdinal(str1, str2) = 48
     str1.Equals(str2) = True
     str2 == str3   True

其實字串的比較還有一個方法Object.ReferenceEquals(str1, str4),不過它是比較兩個字串的物件引用是否相同,例子與使用請檢視第11條:字串拘留池機構。

3、字串的查詢:
(1)、String.Contains(Findstr):引數:Findstr為要查詢的字元或字串;功能:找指定字串是否包含一個字串,返回值的boolean型別,即只有true和false。
(2)、String.IndexOf(Findstr):引數:Findstr為要查詢的字元或字串;功能:查詢FindStr在字串中第一次出現的位置,返回值為第一次出現的下標,沒有找到則返回-1.
(3)、String.LastIndexOf(FindStr):引數:Findstr為要查詢的字元或字串;功能:查詢FindStr在字串中最後一次出現的位置,返回值為最後一次出現的下標,沒有找到則返回-1。

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int nResult = 0;
            bool bResult = false;

            string str = "hello everyOne!!";
            bResult = str.Contains("e");
            Console.WriteLine("Contains(\"e\") = " + bResult);
            nResult = str.IndexOf("e");
            Console.WriteLine("IndexOf(\"e\") = " + nResult);
            nResult = str.LastIndexOf("e");
            Console.WriteLine("LastIndexOf(\"e\") = " + nResult);
        }
    }
}
結果:Contains("e") = True
     IndexOf("e") = 1
     LastIndexOf("e") = 13

(4)、String.IndexOf(Findstr)還有一個過載函式String.indexof(),它的用法如下:
(5)、String.indexof():在字串中從前向後定位字元和字串;所有的返回值都是指在字串的絕對位置,如為空則為-1 。

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int nResult = 0;

            string str = "hello everyOne!!";
            nResult = str.IndexOf('e');    //查詢該字串中的第一次'e'出現位置
            Console.WriteLine("IndexOf('e') = " + nResult);
            nResult = str.IndexOf('e', 1); //查詢該字串中的第一次'e'出現位置
            Console.WriteLine("IndexOf('e', 1) = " + nResult);
            nResult = str.IndexOf('e', 5, 4); //從前向後定位從第5位到第9位中'e'出現的位置; 
            Console.WriteLine("IndexOf('e', 5, 4) = " + nResult);
        }
    }
}
結果:IndexOf('e') = 1
     IndexOf('e', 1) = 1
     IndexOf('e', 5, 4) = 6

4、字串的擷取:
(1)、String.SubString(StartIndex):引數:StartIndex為要進行擷取的開始下標;功能:保留字串中下標從StartIndex開始後面的全部字串。
(2)、String.SubString(StartIndex, Len):引數:StartIndex為要開始擷取的下標,Len為要擷取的長度;功能:保留字串中下標從StartIndex開始後面的Len個長度的字串。

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int nResult = 0;

            string str = "hello everyOne!!";
            string OnePareStr = str.Substring(5);
            string TwoPareStr = str.Substring(5, 6);
            Console.WriteLine("str.Substring(5) = " + OnePareStr);
            Console.WriteLine("str.Substring(5, 6) = " + TwoPareStr);
        }
    }
}
結果:strstr.Substring(5) =  everyOne!!
     str.Substring(5, 6) =  every

5、字串的分割:
String.Split(SplitCh):引數:SplitCh為分割的字元;功能:將字串一SplitCh進行分割,它的返回值是一個字串陣列。

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "hello everyOne!!";
            string[] destStr = str.Split('e');
            Console.Write("str.Split('e') = ");
            foreach (string outstr in destStr)
            {
                Console.Write(outstr);
                Console.Write(" ");
            } 
        }
    }
}
結果:str.Split('e') = h llo  v ryOn !!

6、字串的合併:
(1)、String.Concat(str1, str2, …., strn):將n個字串連線,中間沒有連線符
(2)、String.Join(SplitCh, array):引數:SplitCh為合併後的分隔符,array為要合併的字串陣列;功能:將字串書組合併成一個字串,每個元素之間用SplitCh隔開

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str1 = "hello, ";
            string str2 = "I am very happy!!";
            string[] array= {"hello", "I am", "very happy!!"};
            string ConcatStr = string.Concat(str1, str2);
            String JoinStr = string.Join("|", array);
            Console.WriteLine("string.Concat(str1, str2) = " + ConcatStr);
            Console.WriteLine("string.Join('-', array) = " + JoinStr);
        }
    }
}
結果:string.Concat(str1, str2) = hello, I am very happy!!
     string.Join('-', array) = hello|I am|very happy!!

其實字串連線也可以用 ‘+’ 來實現。

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str1 = "hello, ";
            string str2 = "I am very happy!!";
            string DestStr = str1 + str2;
            Console.WriteLine("str1 + str2 = " + DestStr);
        }
    }
}
結果:str1 + str2 = hello, I am very happy!!

7、字串的替換:
String.Replace(SreStr, ChangeStr):引數:SreStr為要替換的原字串,ChangeStr為用來替換的字串。作用:用ChangeStr來替換字串中的SreStr.

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "I am very happy!!";
            string DestStr = str.Replace("very", "not");
            Console.WriteLine("str.Replace(\"very\", \"not\") = " + DestStr);
        }
    }
}
結果:str.Replace("very", "not") = I am not happy!!

8、字串的插入與填充:
(1)、String.Insert(index, str):index是需要插入的位置,str是要插入的字元;
(2)、String.PadRight(Len, ch):引數:Len為字串的總長度,ch為用來填充的字元。作用:如果字串上都不夠Len,則在結尾用ch來填充
(3)、String.PadLeft(Len, ch):引數:Len為字串的總長度,ch為用來填充的字元。作用:如果字串上都不夠Len,則在開始處用ch來填充

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "I am happy!!";
            string str1 = str.Insert(5, "very ");
            string str2 = str1.PadLeft(30, ' ');
            string str3 = str1.PadRight(30, ' ');
            Console.WriteLine("str.Insert(6, \"very \") = " + str1);
            Console.WriteLine("str1.PadLeft(30, ' ') = " + str2);
            Console.WriteLine("str1.PadRight(30, ' ') = " + str3);
        }
    }
}
結果:str.Insert(6, "very ") = I am very happy!!
     str1.PadLeft(30, ' ') =              I am very happy!!
     str1.PadRight(30, ' ') = I am very happy!!

9、字串的刪除:
(1)、String.Trim():刪除字串中開始和結尾處的空格。
(2)、string.Trim(Param char[]):引數:char[]為想要去掉的字元陣列。功能:去掉字串開始處和結尾處char[]中的所有字元。

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "    #$$I am very happy!!  ##$$  ";
            Console.WriteLine("str.Trim() = " + str.Trim());
            Console.WriteLine("str.Trim(' ', '#', '$') = " + str.Trim(' ', '#', '$'));
        }
    }
}
結果:str.Trim() = #$$I am very happy!!  ##$$
     str.Trim(' ', '#', '$') = I am very happy!!

String.Trim()只能刪除字串開始與結尾的指定字元,而Remove()則可以刪除任意位置的字元(當然,陣列越界則不行呦)。
(4)、String.Remove(Start):Start為需要刪除的起始位置,該方法是將位置後的所有字元全部刪除
(5)、String.Remove(Start, Len):Len是指需要刪除的長度,與上面格式不同的是它是從起始位置開始刪除Len個字元

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "    #I am very happy!!  ## ";
            Console.WriteLine("str.Remove(22) = " + str.Remove(22));
            Console.WriteLine("str.Remove(22, 2) = " + str.Remove(22, 2));
        }
    }
}
結果:str.Remove(22) =     #I am very happy!!
     str.Remove(22, 2) =     #I am very happy!!##

10、字串的大小寫轉換:
(1)、String.ToLower():將字串轉化為小寫形式
(2)、String.ToUpper():將字串轉換威大寫形式

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "Hello, I am very happy!!";
            Console.WriteLine("str.ToLower() = " + str.ToLower());
            Console.WriteLine("str.ToUpper() = " + str.ToUpper());
        }
    }
}
結果:str.ToLower() = hello, i am very happy!!
     str.ToUpper() = HELLO, I AM VERY HAPPY!!

ToLower()和ToUpper()兩種方法都必須用一個string例項來呼叫,並且都會返回一個轉換完成的新字串。

11、字串拘留池機構
同一個程式中,即使將同一個字串復值給多個字串,系統就會多次分配記憶體空間,這樣不僅浪費記憶體,也會影響系統性能,為此,.Net提出了字串拘留池機制。

拘留池機制原理:
使用拘留池後,當CLR啟動後,會在內部建立一個容器,該容器的鍵為字串的內容,值則時字串在託管堆上的引用。這樣的話,每次需要分配一個新字串物件時,在分配記憶體之前先會檢測容器中是否包含了該字串物件,存在則返回已經存在的字串物件的引用,不存在的話才會新分配物件,把它新增到內部容器中,然後再返回該物件的引用。【如果用new分配一個字串物件,字串拘留池機制不會起作用】,原理如下圖:
定義一個字串s1 = “123”:
這裡寫圖片描述
如果此時在給s2也賦值123時,則s2字串變數s2也指向字串物件“123”:
這裡寫圖片描述

那麼CLR儲存的字串拘留池的容器可以訪問嗎?結果是肯定噠,System.String類中提供了兩個靜態方法可以進行訪問:
(1)、public static String Intern (String s):返回字串s在字串拘留池中對應的引用,如果該字串不在字串拘留池中,那麼會新分配一個字串物件並新增到字串拘留池中同時返回該字串的引用。
(2)、public static String IsInterned (String s): 功能與上個方法相似。只是當字串s不在字串拘留池中時,不會分配新的物件,並返回null。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StringTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string str1 = "I am very happy!!";
            string str2 = "I am very happy!!";
            Console.WriteLine(object.ReferenceEquals(str1, str2));  //str1與str2的引用相同
            char[] array1 = { 'I', ' ', 'a', 'm', ' ', 'v', 'e', 'r', 'y', ' ', 'h', 'a', 'p', 'p', 'y', '!', '!'};
            string str4 = new string(array1);
            //str1與str4引用不同的話,就說明使用new時拘留池機制沒有發揮作用
            Console.WriteLine(Object.ReferenceEquals(str1, str4));  

           //str2存在容器中,所以返回的是一個物件的引用
            Console.WriteLine("IsInterned(str2) = " + string.IsInterned(str2));

           char[] array2 = { 't', 'e', 's', 't'};
            string str5 = new string(array2);
            //因為str5使用new分配的,所以str5不存在與內部容器中,所以如果IsInterned(str5)返回null,
            //則說明該方法不會將其新增到拘留池中
            string str6 = string.IsInterned(str5);  
            Console.Write("IsInterned(str5) = ");
            Console.WriteLine(str6 == null ? "null" : "not null"); 

           //同理如果IsInterned(str5)返回null,則說明Intern()方法會先將其新增到拘留池中,然後再返回一個物件引用
            Console.WriteLine("Intern(str6) = " + string.Intern(str5));

            //再用IsInterned()驗證下intern()方法是否將其新增進了容器
            string str7 = string.IsInterned(str5);  
            Console.Write("IsInterned(str5) = ");
            Console.WriteLine(str7 == null ? "null" : "not null"); 
        }
    }
}
結果:True
     False
     IsInterned(str2) = I am very happy!!
     IsInterned(str5) = null
     Intern(str6) = test
     IsInterned(str5) = not null

拘留池機制缺點:
拘留池機制每次在分配記憶體之前,先回在容器內部查詢該字串是否存在,這樣就導致,如果一個程式中字串賦值或者重複讀很低甚至沒有重複時,字串拘留池機制不僅不會潔身記憶體,相反會因為CLR額外的保留了一個儲存字串池的容器,並且在每次進行字串賦值時都要額外的檢查這個容器而帶來負面影響。