網站首頁 編程語言 正文
1. System.Char 字符
char 是 System.Char 的別名。
System.Char 占兩個字節,16個二進制位。
System.Char 用來表示、存儲一個 Unicode 字符。
System.Char 的表示范圍是?U+0000
?到U+FFFF
,char 默認值是?\0
,即?U+0000
。
Unicode 的表示,通常以?U+____
形式表示,即?U
?和 一組16進制的數字組成。
char 有四種賦值方法
char a = 'j'; char b = '\u006A'; char c = '\x006A'; char d = (char) 106; Console.WriteLine($"{a} | {b} | {c} | bsd5o550550j");
輸出
j | j | j | j
\u
?開頭是 Unicode 轉義序列(編碼);使用 Unicode 轉義序列,后面必須是4個十六進制的數字。
\u006A 有效 \u06A 無效 \u6A 無效
\x
?開頭是 十六進制轉義序列,也是由4個十六進制數字組成。如果前面是N個0的話,則可以省略0。下面的示例都是表示同一個字符。
\x006A \x06A \x6A
char 可以隱式轉為其他數值類型,整型有可以轉為ushort
,int
,uint
,long
,和ulong
,浮點型 可以轉為?float
,double
,和decimal
。
char 可以顯式轉為?sbyte
,byte
和short
。
其他類型無法隱式轉為 char 類型,但是任何整型和浮點型都可以顯式轉為 char。
2. 字符處理
System.Char 中,具有很多就態方法,能夠有助于識別、處理字符。
有一個非常重要的 UnicodeCategory 枚舉
public enum UnicodeCategory { UppercaseLetter, LowercaseLetter, TitlecaseLetter, ModifierLetter, OtherLetter, NonSpacingMark, SpacingCombiningMark, EnclosingMark, DecimalDigitNumber, LetterNumber, OtherNumber, SpaceSeparator, LineSeparator, ParagraphSeparator, Control, Format, Surrogate, PrivateUse, ConnectorPunctuation, DashPunctuation, OpenPunctuation, ClosePunctuation, InitialQuotePunctuation, FinalQuotePunctuation, OtherPunctuation, MathSymbol, CurrencySymbol, ModifierSymbol, OtherSymbol, OtherNotAssigned, }
System.Char 中, 有一個?GetUnicodeCategory()
?靜態方法,可以返回字符的類型,即上面的枚舉值。
除了?GetUnicodeCategory()
?,我們還可以通過具體的靜態方法判斷字符的類別。
下面列出靜態方法的使用說明的枚舉類別。
靜態方法 | 說明 | 枚舉表示 |
---|---|---|
IsControl | 值小于0x20 ?的不可打印字符。例如 \r、\n、\t、\0等。 |
無 |
IsDigit | 0-9和其他字母表中的數字 | DecimalDigitNumber |
IsLetter | A-Z、a-z 和其他字母字符 | UppercaseLetter, LowercaseLetter, TitlecaseLetter, ModifierLetter, OtherLetter |
IsLetterOrDigit | 字母和數字 | 參考 IsLetter 和 IsDigit |
IsLower | 小寫字母 | LowercaseLetter |
IsNumber | 數字、Unicode中的分數、羅馬數字 | DecimalDigitNumber, LetterNumber, OtherNumber |
IsPunctuation | 西方和其他字母表中的標點符號 | ConnectorPunctuation, DashPunctuation, InitialQuotePunctuation, FinalQuotePunctuation, OtherPunctuation |
IsSeparator | 空格和所有的 Unicode 分隔符 | SpaceSeparator, ParagraphSeparator |
IsSurrogate | 0x10000到0x10FFF之間的Unicode值 | Surrogate |
IsSymbol | 大部分可打印字符 | MathSymbol, ModifierSymbol, OtherSymbol |
IsUpper | 大小字母 | UppercaseLetter |
IsWhiteSpace | 所有的分隔符以及 \t、\n、\r、\v、\f | SpaceSeparator, ParagraphSeparator |
示例
char chA = 'A'; char ch1 = '1'; string str = "test string"; Console.WriteLine(chA.CompareTo('B')); //----------- Output: "-1 //(meaning 'A' is 1 less than 'B') Console.WriteLine(chA.Equals('A')); //----------- Output: "True" Console.WriteLine(Char.GetNumericValue(ch1)); //----------- Output: "1" Console.WriteLine(Char.IsControl('\t')); //----------- Output: "True" Console.WriteLine(Char.IsDigit(ch1)); //----------- Output: "True" Console.WriteLine(Char.IsLetter(',')); //----------- Output: "False" Console.WriteLine(Char.IsLower('u')); //----------- Output: "True" Console.WriteLine(Char.IsNumber(ch1)); //----------- Output: "True" Console.WriteLine(Char.IsPunctuation('.')); //----------- Output: "True" Console.WriteLine(Char.IsSeparator(str, 4)); //----------- Output: "True" Console.WriteLine(Char.IsSymbol('+')); //----------- Output: "True" Console.WriteLine(Char.IsWhiteSpace(str, 4)); //----------- Output: "True" Console.WriteLine(Char.Parse("S")); //----------- Output: "S" Console.WriteLine(Char.ToLower('M')); //----------- Output: "m" Console.WriteLine('x'.ToString()); //----------- Output: "x" Console.WriteLine(Char.IsSurrogate('\U00010F00')); // Output: "False" char test = '\xDFFF'; Console.WriteLine(test); //----------- Output:'?' Console.WriteLine( Char.GetUnicodeCategory(test));//----------- Output:"Surrogate"
如果想滿足你的好奇心,可以點擊?http://www1.cs.columbia.edu/~lok/csharp/refdocs/System/types/Char.html
3. 全球化
C# 中 System.Char 有很豐富的方法去處理字符,例如常用的?ToUpper
、ToLower
?。
但是字符的處理,會受到用戶語言環境的影響。
使用 System.Char 中的方法處理字符時,可以調用帶有?Invariant
?后綴的方法或使用?CultureInfo.InvariantCulture
,以進行與語言環境無關的字符處理。
示例
Console.WriteLine(Char.ToUpper('i',CultureInfo.InvariantCulture)); Console.WriteLine(Char.ToUpperInvariant('i'));
對于字符和字符串處理,可能用到的重載參數和處理方式,請看下面的說明。
StringComparison
枚舉 | 枚舉值 | 說明 |
---|---|---|
CurrentCulture | 0 | 使用區分文化的排序規則和當前區域性來比較字符串 |
CurrentCultureIgnoreCase | 1 | 使用對區域性敏感的排序規則,當前區域性來比較字符串,而忽略要比較的字符串的大小寫 |
InvariantCulture | 2 | 使用區分文化的排序規則和不變區域性比較字符串 |
InvariantCultureIgnoreCase | 3 | 使用區分區域性的排序規則,不變區域性來比較字符串,而忽略要比較的字符串的大小寫 |
Ordinal | 4 | 使用序數(二進制)排序規則比較字符串 |
OrdinalIgnoreCase | 5 | 使用序數(二進制)排序規則比較字符串,而忽略要比較的字符串的大小寫 |
CultureInfo
枚舉 | 說明 |
---|---|
CurrentCulture | 獲取表示當前線程使用的區域性的 CultureInfo對象 |
CurrentUICulture | 獲取或設置 CultureInfo對象,該對象表示資源管理器在運行時查找區域性特定資源時所用的當前用戶接口區域性 |
InstalledUICulture | 獲取表示操作系統中安裝的區域性的 CultureInfo |
InvariantCulture | 獲取不依賴于區域性(固定)的 CultureInfo 對象 |
IsNeutralCulture | 獲取一個值,該值指示當前 CultureInfo 是否表示非特定區域性 |
4. System.String 字符串
4.1 字符串搜索
字符串有多個搜索方法:StartsWith()
、EndsWith()
、Contains()
、IndexOf
。
StartsWith()
?和?EndsWith()
?可以使用 StringComparison 比較方式、CultureInfo 控制文化相關規則。
StartsWith()
?:字符串開頭是否存在符合區配字符串
EndsWith()
: 字符串結尾是否存在符合區配字符串
Contains()
: 字符串任意位置是否存在區配字符串
IndexOf
: 字符串或字符首次出現的索引位置,如果返回值為?-1
?則表示無區配結果。
使用示例
string a = "癡者工良(高級程序員勸退師)"; Console.WriteLine(a.StartsWith("高級")); Console.WriteLine(a.StartsWith("高級",StringComparison.CurrentCulture)); Console.WriteLine(a.StartsWith("高級",true, CultureInfo.CurrentCulture)); Console.WriteLine(a.StartsWith("癡者",StringComparison.CurrentCulture)); Console.WriteLine(a.EndsWith("勸退師)",true, CultureInfo.CurrentCulture)); Console.WriteLine(a.IndexOf("高級",StringComparison.CurrentCulture));
輸出
False False False True True 5
除了?Contains()
,其它三種方法都有多個重載方法,例如
重載 | 說明 |
---|---|
(String) | 是否與指定字符串區配 |
(String, StringComparison) | 以何種方式指定字符串區配 |
(String, Boolean, CultureInfo) | 控制大小寫和文化規則指定字符串區配 |
這些與全球化和大小寫區配的規則,在后面章節中會說到。
4.2 字符串提取、插入、刪除、替換
4.2.1 提取
SubString()
?方法可以在提取字符串指定索開始的N個長度或余下的所有的字符。
string a = "癡者工良(高級程序員勸退師)"; string a = "癡者工良(高級程序員勸退師)"; Console.WriteLine(a.Substring(startIndex: 1, length: 3)); // 者工良 Console.WriteLine(a.Substring(startIndex: 5)); // 高級程序員勸退師)
4.2.2 插入、刪除、替換
Insert()
?:指定索引位置后插入字符或字符串
Remove()
?:指定索引位置后插入字符或字符串
PadLeft()
?:在字符串左側將使用某個字符串擴展到N個字符長度
PadRight()
:在字符串右側將使用某個字符串擴展到N個字符長度
TrimStart()
?:從字符串左側開始刪除某個字符,碰到不符合條件的字符即停止。
TrimEnd()
?:從字符串右側開始刪除某個字符,碰到不符合條件的字符即停止。
Replace()
:將字符串中的N連續個字符組替換為新的M個字符組。
示例
string a = "癡者工良(高級程序員勸退師)"; // length = 14 Console.WriteLine("\n - Remove Insert - \n"); Console.WriteLine(a.Insert(startIndex: 4, value: "我是")); Console.WriteLine(a.Remove(startIndex: 5)); Console.WriteLine(a.Remove(startIndex: 5, count: 3)); Console.WriteLine("\n - PadLeft PadRight - \n"); Console.WriteLine(a.PadLeft(totalWidth: 20, paddingChar: '*')); Console.WriteLine(a.PadRight(totalWidth: 20, paddingChar: '#')); Console.WriteLine(a.PadLeft(totalWidth: 20, paddingChar: '\u0023')); Console.WriteLine(a.PadRight(totalWidth: 20, paddingChar: '\u002a')); Console.WriteLine(a.PadLeft(totalWidth: 18, paddingChar: '.')); Console.WriteLine(a.PadRight(totalWidth: 18, paddingChar: '.')); Console.WriteLine("\n - Trim - \n"); Console.WriteLine("|Hello | World|".Trim('|')); Console.WriteLine("|||Hello | World|||".Trim('|')); Console.WriteLine("|Hello | World!|".TrimStart('|')); Console.WriteLine("|||Hello | World!|||".TrimStart('|')); Console.WriteLine("|Hello | World!|".TrimEnd('|')); Console.WriteLine("|||Hello | World!|||".TrimEnd('|')); Console.WriteLine("||||||||||||||||||||||||".TrimEnd('|')); Console.WriteLine("*#&abc ABC&#*".TrimStart(new char[] {'*', '#', '&'})); Console.WriteLine("*#&abc ABC&#*".TrimStart(new char[] {'#', '*', '&'})); Console.WriteLine("\n - Replace - \n"); Console.WriteLine("abcdABCDabcdABCD".Replace(oldChar: 'a', newChar: 'A'));
輸出
- Remove Insert - 癡者工良我是(高級程序員勸退師) 癡者工良( 癡者工良(序員勸退師) - PadLeft PadRight - ******癡者工良(高級程序員勸退師) 癡者工良(高級程序員勸退師)###### ######癡者工良(高級程序員勸退師) 癡者工良(高級程序員勸退師)****** ....癡者工良(高級程序員勸退師) 癡者工良(高級程序員勸退師).... - Trim - Hello | World Hello | World Hello | World!| Hello | World!||| |Hello | World! |||Hello | World! abc ABC&#* abc ABC&#* - Replace - AbcdABCDAbcdABCD
5. 字符串駐留池
以下為筆者個人總結,限于水平,如若有錯,望各位加以批評指正。
字符串 駐留池是在域(Domain)級別完成的,而字符串駐留池可以在域中的所有程序集之間共享。
CLR 中維護著一個叫做駐留池(Intern Pool)的表。
這個表記錄了所有在代碼中使用字面量聲明的字符串實例的引用。
拼接方式操作字面量時,新的字符串又會進入字符串駐留池。
只有使用使用字面量聲明的字符串實例,實例才會對字符串駐留池字符串引用。
而無論是字段屬性或者是方法內是聲明的 string 變量、甚至是方法參數的默認值,都會進入字符串駐留池。
例如
static string test = "一個測試"; static void Main(string[] args) { string a = "a"; Console.WriteLine("test:" + test.GetHashCode()); TestOne(test); TestTwo(test); TestThree("一個測試"); } public static void TestOne(string a) { Console.WriteLine("----TestOne-----"); Console.WriteLine("a:" + a.GetHashCode()); string b = a; Console.WriteLine("b:" + b.GetHashCode()); Console.WriteLine("test - a :" + Object.ReferenceEquals(test, a)); } public static void TestTwo(string a = "一個測試") { Console.WriteLine("----TestTwo-----"); Console.WriteLine("a:" + a.GetHashCode()); string b = a; Console.WriteLine("b:" + b.GetHashCode()); Console.WriteLine("test - a :" + Object.ReferenceEquals(test, a)); } public static void TestThree(string a) { Console.WriteLine("----TestThree-----"); Console.WriteLine("a:" + a.GetHashCode()); string b = a; Console.WriteLine("b:" + b.GetHashCode()); Console.WriteLine("test - a :" + Object.ReferenceEquals(test, a)); }
輸出結果
test:-407145577 ----TestOne----- a:-407145577 b:-407145577 test - a :True ----TestTwo----- a:-407145577 b:-407145577 test - a :True ----TestThree----- a:-407145577 b:-407145577 test - a :True
可以通過靜態方法?Object.ReferenceEquals(s1, s2);?
或者 實例的?.GetHashCode()
?來對比兩個字符串是否為同一個引用。
可以使用不安全代碼,直接修改內存中的字符串
參考?https://blog.benoitblanchon.fr/modify-intern-pool/
string a = "Test"; fixed (char* p = a) { p[1] = '3'; } Console.WriteLine(a);
使用?*Microsoft.Diagnostics.Runtime*
?可以獲取 CLR 的信息。
結果筆者查閱大量資料發現,.NET 不提供 API 去查看字符串常量池里面的哈希表。
原文鏈接:https://www.cnblogs.com/whuanle/p/11967014.html
相關推薦
- 2022-08-30 DOM節點對象 、獲取節點、節點屬性、動態操作DOM節點、toList1.0/toList2.0、
- 2022-07-21 UIStackView嵌套的Label多行文字動態高度
- 2023-02-07 Redis?中ZSET數據類型命令使用及對應場景總結(案例詳解)_Redis
- 2022-06-26 django中模板繼承與ModelForm實例詳解_python
- 2022-08-21 C語言數據結構之單鏈表的實現_C 語言
- 2023-02-14 Android?SharedPreference存儲文件三步走_Android
- 2022-05-03 ASP.NET?Core基于滑動窗口實現限流控制_實用技巧
- 2022-04-04 使用Docker安裝Nginx并配置端口轉發問題及解決方法_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支