C#中的char、string和StringBuilder的使用詳解
char 字符
char代表一個(gè)Unicode字符,它是System.Char的別名
char someChar = 'a';//定義了一個(gè)字符 char newLine= '\n';//這是一個(gè)換行符
System.Char定義了一組靜態(tài)方法:
- ToUpper 將指定的字符轉(zhuǎn)換為等效的大寫(xiě)形式
- ToLower 將指定的字符轉(zhuǎn)換為等效的小寫(xiě)形式
- IsWhiteSpace 判斷指定的字符是否為空白字符
- ……
例子:
Console.WriteLine(char.ToUpper('c'));//輸出的是一個(gè)大寫(xiě)的C Console.WriteLine(char.ToLower('c'));//輸出的是還是它自己 Console.WriteLine(char.ToUpper('C'));//輸出的是還是它自己 Console.WriteLine(char.ToLower('C'));//輸出的是一個(gè)小寫(xiě)的c Console.WriteLine(char.IsWhiteSpace('c'));//輸出為False Console.WriteLine(char.IsWhiteSpace('\t'));//輸出為T(mén)rue Console.WriteLine(char.IsWhiteSpace(' '));//輸出為T(mén)rue
可以通過(guò)char或者System.Char來(lái)調(diào)用
例子:
Console.WriteLine(char.ToUpper('c'));//輸出的是一個(gè)大寫(xiě)的C Console.WriteLine(System.Char.ToUpper('c'));//輸出的是一個(gè)大寫(xiě)的C
現(xiàn)在這邊會(huì)有一個(gè)問(wèn)題,可能會(huì)引起一個(gè)bug,就是ToUpper,ToLower會(huì)遵循用戶的地區(qū)設(shè)置,例如,char.ToUpper('i') == 'I',這句話在土耳其地區(qū)設(shè)置里就會(huì)返回False。
解決辦法就是使用culture-invariant版本的方法,總會(huì)應(yīng)用英語(yǔ)的Culture
- ToUpperInvariant
- ToLowerInvariant
例子:
//使用固定區(qū)域性的大小寫(xiě)規(guī)則,不依賴(lài)于區(qū)域性的設(shè)置,以下這兩種方式是等價(jià)的 Console.WriteLine(char.ToUpperInvariant('i'));//輸出的是大寫(xiě)的I Console.WriteLine(char.ToUpper('i', CultureInfo.InvariantCulture));
char是16bit的,足夠代表基本多語(yǔ)言平面的任何Unicode字符,如果超出這個(gè)范圍,那么必須使用surrogate pairs。
string 字符串
- string是System.String的別名
- string是不可變的
- string是字符的序列
如何構(gòu)建string
例子:
string s1 = "Hello"; string s2 = "First Line\r\nSecond Line"; string s3 = @\\server\fileshare\helloworld.cs;
創(chuàng)建重復(fù)字符的字符串
使用string的構(gòu)造函數(shù)創(chuàng)建一個(gè)重復(fù)指定次數(shù)的字符的字符串。
例子:
Console.WriteLine(new string('*', 10));//輸出的結(jié)果就是**********
可以從char數(shù)組構(gòu)建字符串
例子:
char[] ca = "Hello".ToCharArray(); string s = new string(ca);
ToCharArray的作用正好相反,把字符串轉(zhuǎn)成字符數(shù)組。
string的構(gòu)造函數(shù)也被重載用來(lái)接收各種(不安全的)指針類(lèi)型,目的是從像char*這樣的類(lèi)型創(chuàng)建字符串。
Null 和 空string
空string的長(zhǎng)度是0,通過(guò)literal或string.Empty靜態(tài)字段來(lái)創(chuàng)建
相等性比較的例子:
string empty = ""; Console.WriteLine(empty == ""); // True Console.WriteLine(empty == string.Empty); // True Console.WriteLine(empty.Length == 0); // True
string可以為null,因?yàn)槭且妙?lèi)型
string nullString = null; Console.WriteLine(nullString == null); // True Console.WriteLine(nullString == ""); // False Console.WriteLine(nullString.Length == 0); // NullReferenceException
靜態(tài)的string.IsNullOrEmpty通常用來(lái)判斷字符串是否為空或者null,我習(xí)慣性使用IsNullOrWhiteSpace,這個(gè)判斷字符串是否為空或者null或者空白的字符。
訪問(wèn)string里的字符
通過(guò)索引器
string str = "abcd"; char letter = str[1]; // letter = 'b'
string實(shí)現(xiàn)了IEnumerable<char>接口,所以可以foreach里面的每個(gè)元素
// 分別依次輸出字符1 、2 、3 foreach (var item in "123") { Console.WriteLine(item); }
在string里進(jìn)行搜索
最簡(jiǎn)單的方法包括:StartsWith,EndsWith和Contains。返回的是true或者false。
Console.WriteLine("HelloWorld.cs".EndsWith(".cs")); // 返回結(jié)果為T(mén)rue Console.WriteLine("HelloWorld.cs".Contains("World")); // 返回結(jié)果為T(mén)rue Console.WriteLine("HelloWorld.cs".EndsWith(".CS")); // 返回結(jié)果為False Console.WriteLine("HelloWorld.cs".Contains("world")); // 返回結(jié)果為False
StartsWith,EndsWith的重載方法允許你指定一個(gè)StringComparison枚舉或一個(gè)CultureInfo對(duì)象,以便控制大小寫(xiě)和區(qū)域文化的敏感性,默認(rèn)使用當(dāng)前本地化的區(qū)域設(shè)置(locale),并且區(qū)分大小寫(xiě)。
Console.WriteLine("HelloWorld.cs".StartsWith("hello", StringComparison.InvariantCultureIgnoreCase)); // 返回結(jié)果為T(mén)rue
Contains沒(méi)有提供類(lèi)似的重載方法,但是你可以使用IndexOf方法,它會(huì)返回給定字符/子字符串在被搜索字符串里的首個(gè)位置。
同時(shí),IndexOf提供了重載方法,它可以接收一個(gè)起始位置參數(shù)(開(kāi)始搜索的索引值),以及一個(gè)StringComparison枚舉
Console.WriteLine("abcde".IndexOf("cd")); // 結(jié)果為2 Console.WriteLine("abcde abcde".IndexOf("CD", 6, StringComparison.CurrentCultureIgnoreCase)); // 結(jié)果為8
LastIndexOf,它和IndexOf類(lèi)似,但是它是反向搜索
IndexOfAny,它會(huì)返回一組字符里任意一個(gè)元素的第一個(gè)匹配的位置。
Console.WriteLine("abc,de f".IndexOfAny(new char[] { ' ', ',' })); // 結(jié)果為3 Console.WriteLine("sdgp5jesu5fa9afe0".IndexOfAny("0123456789".ToCharArray())); // 結(jié)果為4
LastIndexOfAny,功能類(lèi)似,方向相反
操縱或者控制 string
因?yàn)閟tring是不可變的,所以所有操縱string的方法返回的都是一個(gè)新的string,原來(lái)的string是原封不動(dòng)的。
Substring,會(huì)抽取字符串的一部分出來(lái)。
string left3 = "12345".Substring(0, 3); // 結(jié)果就是123 string mid3 = "12345".Substring(1, 3); // 結(jié)果為234 //如果忽略長(zhǎng)度,那么就從起始位置一直到字符串的最后 string end3 = "12345".Substring(2); // 結(jié)果為345
Insert、Remove,在指定的位置插入、移除字符串。
string s1 = "helloworld".Insert(5, ","); // 結(jié)果為hello,world string s2 = s1.Remove(5, 1); // 結(jié)果為helloworld
PadLeft、PadRight,會(huì)使用指定的字符(沒(méi)有指定就是空格)填充string,以達(dá)到指定的長(zhǎng)度(如果string原本長(zhǎng)度就長(zhǎng)于指定的長(zhǎng)度,那么它就不變)。
Console.WriteLine("12345".PadLeft(10, '*')); // 輸出結(jié)果就是*****12345 Console.WriteLine("12345".PadLeft(10)); // 輸出結(jié)果就是 12345
TrimStart,TrimEnd從開(kāi)始或結(jié)尾移除指定的字符(默認(rèn)是空白符:空格,tab,換行以及Unicode里相應(yīng)的變種)。
Trim,會(huì)把開(kāi)始和結(jié)尾的空白字符都移除。
Console.WriteLine(" abc \r\n ".Trim().Length); // 結(jié)果為3
Replace,替換所有指定的字符/字符串,(非重疊的)。
Console.WriteLine("hello world".Replace(" ", " | ")); // 結(jié)果為hello | world Console.WriteLine("hello world".Replace(" ", "")); // 結(jié)果為helloworld
ToUpper,ToLower,返回string的大/小寫(xiě)等等效形式。默認(rèn)情況下也遵循用戶當(dāng)前的語(yǔ)言設(shè)定,與上面的char的方法一樣,不再贅述。
拆分、合并字符串
Split方法可以拆分字符串。
- 默認(rèn)使用空格作為分隔符
- 重載方法可以接收param字符數(shù)組,或string作為分隔符
- 可選接收StringSplitOptions枚舉作為參數(shù),有個(gè)選項(xiàng)可以移除空的字符串
string[] words = "my name is bob".Split(); //打印結(jié)果依次輸出my name is bob四個(gè)單詞 foreach (var item in words) { Console.WriteLine(item); } string[] split1 = "123-abc".Split('-'); //打印結(jié)果依次輸出123和abc兩個(gè)字符串 foreach (var item in split1) { Console.WriteLine(item); } string[] split2 = "123-abc-".Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries); //打印結(jié)果依次輸出123和abc兩個(gè)字符串,最后一個(gè)空項(xiàng)會(huì)被移除 foreach (var item in split2) { Console.WriteLine(item); }
Join(靜態(tài))方法,功能與Split相反,用于合并成一個(gè)字符串,它需要一個(gè)分隔符和字符串?dāng)?shù)組。
string[] words = "my name is bob".Split(); Console.WriteLine(string.Join(",", words)); // 輸出結(jié)果為一個(gè)字符串my,name,is,bob
Concat(靜態(tài))方法,和Join類(lèi)似,但是只接收params string數(shù)組作為參數(shù),無(wú)需分隔符。和+的效果一樣,起始編譯器就是把它翻譯成+。
string str1 = string.Concat("hello", "world"); // 結(jié)果為helloworld string str2 = "hello" + "world"; // 結(jié)果為helloworld
String.Format 和 復(fù)合格式的string
Format(靜態(tài))方法,提供了一個(gè)方便的方式來(lái)構(gòu)建嵌入變量的字符串,嵌入的變量/值可以是任何類(lèi)型,F(xiàn)ormat會(huì)調(diào)用它們的ToString方法。
含有嵌入變量的string就叫做復(fù)合格式string(composite format string)。
當(dāng)你調(diào)用String.Format的時(shí)候,你就得傳入一個(gè)復(fù)合格式string,后邊跟著它里面嵌入的這些變量。
string composite = "ab{0}cd{1}e"; Console.WriteLine(string.Format(composite, "123", 456)); // 結(jié)果為ab123cd456e
大括號(hào)里的每個(gè)數(shù)字都叫做格式化項(xiàng)(format item),數(shù)值對(duì)應(yīng)參數(shù)(argument)的位置,并且后邊可以跟著:
- 一個(gè)逗號(hào),和一個(gè)要應(yīng)用的最小寬度(通常用來(lái)對(duì)齊列,負(fù)數(shù)表示左對(duì)齊,正數(shù)表示右對(duì)齊)
- 一個(gè)冒號(hào),和一個(gè)格式化字符串(format string)
string composite = "Name={0, -20} Credit Limit={1,15:C}"; Console.WriteLine(string.Format(composite, "Bob", 500)); Console.WriteLine(string.Format(composite, "Elizatech", 20000));
結(jié)果如下:
從C#6開(kāi)始,你可以使用字符串插值的方式(interpolated string literals)。
int value = 32; Console.WriteLine($"abc{value}"); //結(jié)果為abc32
比較 string
在.NET里,用來(lái)比較兩個(gè)string的概念有兩個(gè):
- 相等性比較,Equality
- 順序比較,Order
相等性比較就是測(cè)試兩個(gè)字符串實(shí)例在語(yǔ)義上是否相等。而順序比較是指在正序倒序排列的時(shí)候,誰(shuí)應(yīng)該出現(xiàn)在前面。
相等性比較不是順序比較的子集。
對(duì)于字符串相等性的比較來(lái)說(shuō),可以使用:
- == 運(yùn)算符
- string的某個(gè)Equals方法(這種方式有很多選項(xiàng))
上述兩種方式還有一個(gè)重要的差別就是,如果string變量轉(zhuǎn)換成了object對(duì)象,那么==運(yùn)算符就不再可靠了。
對(duì)于字符串的順序比較來(lái)說(shuō),可以使用:
- 實(shí)例的CompareTo方法
- 靜態(tài)的Compare和CompareOrdinal方法。第一個(gè)值在第二個(gè)值的后邊,返回正數(shù),第一個(gè)值在第二個(gè)值的前邊,返回負(fù)數(shù),兩個(gè)值并列,返回0。
序數(shù) VS 文化 比較(Ordinal VS Culture Comparison)
有兩個(gè)基本的算法用來(lái)做string比較:
- Ordinal
- Culture-sensitive
Ordinal比較,會(huì)把字符解析成數(shù)字(根據(jù)它們的Unicode數(shù)值),例如:A 是 U+0041,a 是 U+0061。
Culture-sensitive比較,通過(guò)引用特定的字母表來(lái)解析字符。
兩個(gè)常用或者特殊的Culture:
- 當(dāng)前的Culture
- Invariant Culture
對(duì)于相等性比較而言,Ordinal和Culture-specific算法都有用。而對(duì)于順序比較來(lái)說(shuō),更傾向于culture-specific比較(文化相關(guān)的),按字母表對(duì)string進(jìn)行排序,所以肯定需要一個(gè)字母表。
Ordinal依賴(lài)于Unicode的Code point數(shù)值,英文字母正好是字母表的順序,不知道是這么設(shè)計(jì)的還是巧合。
例子:
如果考慮大小寫(xiě),對(duì)一下三個(gè)字符串排序:
"Ada", "Tom", "ada"
Invariant Culture算法的排序結(jié)果是:"ada", "Ada","Tom"
Invariant Culture算法封裝了字母表,并且認(rèn)為大寫(xiě)字母所對(duì)應(yīng)的小寫(xiě)字母是相鄰的(aAbBcC…)。
Ordinal算法的排序結(jié)果是:"Ada","Tom", "ada"
Ordinal算法里,大寫(xiě)字母都在前面,小寫(xiě)字母都在后面(A…Z,a…z)。
盡管Ordinal算法有一定限制,但是==運(yùn)算符在進(jìn)行string相等性比較的時(shí)候,總會(huì)考慮ordinal大小寫(xiě)。實(shí)例版的string.Equals方法如果不傳參數(shù)的話,效果也是一樣,這就是string類(lèi)型的默認(rèn)的相等性比較行為。
Ordinal算法被string的==和Equals函數(shù)選擇,是因?yàn)樗母咝Ш痛_定性。
下面這兩個(gè)方法可以設(shè)定是否考慮Culture和大小寫(xiě)進(jìn)行string比較:
public static bool Equals(String a, String b, StringComparison comparisonType); public bool Equals(String value, StringComparison comparisonType);
靜態(tài)版本的方法優(yōu)勢(shì)在于:如果兩個(gè)字符串有null的情況,那么仍然可以正常工作。
StringComparison有哪些值呢:
下面我們來(lái)看幾個(gè)例子:
Console.WriteLine("Hello" == "hello" ); // False Console.WriteLine(string.Equals("Hello", "hello", StringComparison.OrdinalIgnoreCase)); // True Console.WriteLine("u" == "ü"); // False Console.WriteLine(string.Equals("u", "ü", StringComparison.CurrentCulture)); // ?
string排序比較,string的示例方法是CompareTo,會(huì)執(zhí)行culture相關(guān)的、大小寫(xiě)相關(guān)的排序比較。與string的相等性比較不同,CompareTo沒(méi)有使用Ordinal比較算法,對(duì)于排序來(lái)說(shuō),Culture敏感的算法更有用。
方法的定義:
public int CompareTo(String strB);
CompareTo實(shí)例方法實(shí)現(xiàn)了泛型IComparable接口,該接口在.NET里面是一個(gè)標(biāo)準(zhǔn)的比較協(xié)議。
而對(duì)于其它類(lèi)型的比較,可以使用靜態(tài)的Compare和CompareOrdinal方法。
所有的排序比較方法都會(huì)返回一個(gè):正數(shù)/負(fù)數(shù)/0
第一個(gè)值在第二個(gè)值的后面,返回正數(shù);第一個(gè)值在第二個(gè)值的前面,返回負(fù)數(shù);兩個(gè)值并列,返回0。
Console.WriteLine("Base".CompareTo("Auto")); // 返回1 Console.WriteLine("Base".CompareTo("Base")); // 返回0 Console.WriteLine("Base".CompareTo("China")); // 返回-1 Console.WriteLine("base".CompareTo("Base")); // 返回-1 Console.WriteLine(string.Compare("base", "Base", true)); // 返回0
CultureInfo 對(duì)象
使用CultureInfo對(duì)象,就可以插入任何一個(gè)字母表
CultureInfo這個(gè)類(lèi)是定義在System.Globalization命名空間下的
CultureInfo german = CultureInfo.GetCultureInfo("de-DE"); Console.WriteLine(string.Compare("Müller", "Muller", false, german)); // 返回結(jié)果是1
StringBuilder
StringBuilder類(lèi)(System.Text命名空間)代表的是可編輯或者叫可改變的字符串
使用StringBuilder,你可以Append追加、Insert插入、Remove移除和Replace替換子字符串,而不用替換整個(gè)StringBuilder。
StringBuilder的構(gòu)造函數(shù)可可以接收一個(gè)初始化的string值,以及內(nèi)部容量的初始大小(默認(rèn)是16字符)。如果超過(guò)了這個(gè)大小,StringBuilder會(huì)自動(dòng)重新改變其內(nèi)部結(jié)構(gòu)的大?。ㄝp微的性能損耗)以適應(yīng)最大容量(默認(rèn)是int.MaxValue)。
AppendLine,會(huì)執(zhí)行Append動(dòng)作,區(qū)別在于此操作會(huì)自定添加一個(gè)換行(Windows環(huán)境下是"\r\n")。
StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("123"); stringBuilder.Append("456"); Console.WriteLine(stringBuilder.ToString()); // 結(jié)果為123456 stringBuilder.AppendLine("789"); Console.WriteLine(stringBuilder.ToString()); // 結(jié)果是123456789后面換行了 stringBuilder.AppendLine("abc"); Console.WriteLine(stringBuilder.ToString());
AppendFormat,接收一個(gè)復(fù)合格式字符串,和string.Format一樣。
StringBuilder還有一個(gè)Length屬性,獲取長(zhǎng)度的屬性。
StringBuilder還有一個(gè)索引器,用來(lái)讀取每個(gè)字符的可寫(xiě)的索引器。
想要清除StringBuilder的內(nèi)容,可以初始化一個(gè)新的StringBuilder,或者把Length屬性設(shè)為0。但是把StringBuilder的Length屬性設(shè)為0并沒(méi)有縮小它的容量,它占用的內(nèi)存大小是不變的,想要釋放內(nèi)容,必須要new一個(gè),而且要保證原來(lái)的示例可以被GC。
到此這篇關(guān)于C#中的char、string和StringBuilder的使用詳解的文章就介紹到這了,更多相關(guān)C# char、string和StringBuilder內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#如何動(dòng)態(tài)創(chuàng)建lambda表達(dá)式
這篇文章主要介紹了C#如何動(dòng)態(tài)創(chuàng)建lambda表達(dá)式問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02C# 添加對(duì)System.Configuration.dll文件的引用操作
這篇文章主要介紹了C# 添加對(duì)System.Configuration.dll文件的引用操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01Unity UGUI實(shí)現(xiàn)滑動(dòng)翻頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了Unity UGUI實(shí)現(xiàn)滑動(dòng)翻頁(yè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析
這篇文章主要介紹了WinForm中KeyDown,KeyPress和KeyUp的順序與區(qū)別解析,對(duì)C#初學(xué)者來(lái)說(shuō)很有學(xué)習(xí)借鑒價(jià)值,需要的朋友可以參考下2014-08-08Microsoft Expression Web 簡(jiǎn)體中文正式版 官方下載地址
Microsoft Expression Web 簡(jiǎn)體中文正式版 官方下載地址...2007-07-07