C# 字符串
from: C# string tutorial
C#提供了别名string来代表System.String类。如果在代码中使用String类,必须载入包 using System;而使用内建的别名string则不需要。
文本在内部存储为 Char 对象的依序只读集合。 在 C# 字符串末尾没有 null 终止字符;因此,一个 C# 字符串可以包含任何数量的嵌入的 null 字符 ('\0')。 字符串的 Length 属性表示其包含的 Char 对象数量,而非 Unicode 字符数。 若要访问字符串中的各个 Unicode 码位,请使用 StringInfo 对象。
声明和初始化字符串
请注意,不要使用 new 运算符创建字符串对象,除非使用字符数组初始化字符串。
使用 Empty 常量值初始化字符串,以新建字符串长度为零的 String 对象。 长度为零的字符串文本表示法是“”。 通过使用 Empty 值(而不是 null)初始化字符串,可以减少 NullReferenceException 发生的可能性。 尝试访问字符串前,先使用静态 IsNullOrEmpty(String) 方法验证字符串的值。
字符串对象的不可变性
字符串对象是“不可变的”:它们在创建后无法更改。 看起来是在修改字符串的所有 String 方法和 C# 运算符实际上都是在新的字符串对象中返回结果。
转义字符和逐字字符串
常规字符串自动转义字符。关于字符串转义序列,请查询官网:转义序列。
当字符串文本包含反斜杠字符(例如在文件路径中)时,出于便捷性和更强的可读性的考虑,使用逐字字符串。 由于逐字字符串将新的行字符作为字符串文本的一部分保留,因此可将其用于初始化多行字符串。 使用双引号在逐字字符串内部嵌入引号。
string filePath = @"C:\Users\scoleridge\Documents\"; //Output: C:\Users\scoleridge\Documents\ string text = @"My pensive SARA ! thy soft cheek reclined Thus on mine arm, most soothing sweet it is To sit beside our Cot,..."; /* Output: My pensive SARA ! thy soft cheek reclined Thus on mine arm, most soothing sweet it is To sit beside our Cot,... */ string quote = @"Her name was ""Sara."""; //Output: Her name was "Sara."
格式化字符串
使用静态 Format 方法,并在大括号中嵌入将在运行时被其他值替换的占位符,从而创建格式字符串。
WriteLine 方法的一个重载将格式字符串用作参数。 因此,可以仅嵌入格式字符串文本,而无需显式调用该方法。 不过,如果使用 WriteLine 方法在 Visual Studio“输出”窗口中显示调试输出,必须显式调用 Format 方法,因为 WriteLine 仅接受字符串,而不接受格式字符串。
子字符串
string s3 = "Visual C# Express"; System.Console.WriteLine(s3.Substring(7, 2)); // Output: "C#" System.Console.WriteLine(s3.Replace("C#", "Basic")); // Output: "Visual Basic Express" // Index values are zero-based int index = s3.IndexOf("C"); // index = 7
访问单个字符
由于System.String对象只能够访问字符,而无法修改,可以换用 StringBuilder 对象重新实现字符串。
string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?"; System.Text.StringBuilder sb = new System.Text.StringBuilder(question);
Null 字符串和空字符串
空字符串是包含零个字符的 System.String 对象实例。 赋值如下: string s = String.Empty;
相比较而言,null 字符串并不指 System.String 对象实例,只要尝试对 null 字符串调用方法,都会引发 NullReferenceException。 但是,可以在串联和与其他字符串的比较操作中使用 null 字符串。
string str = "hello"; string nullStr = null; string emptyStr = String.Empty; string tempStr = str + nullStr; // Output of the following line: hello Console.WriteLine(tempStr); bool b = (emptyStr == nullStr); // Output of the following line: False Console.WriteLine(b); // The following line creates a new empty string. string newStr = emptyStr + nullStr; // Null strings and empty strings behave differently. The following // two lines display 0. Console.WriteLine(emptyStr.Length); Console.WriteLine(newStr.Length); // The following line raises a NullReferenceException. Console.WriteLine(nullStr.Length); // The null character can be displayed and counted, like other chars. string s1 = "\x0" + "abc"; string s2 = "abc" + "\x0"; // Output of the following line: * abc* Console.WriteLine("*" + s1 + "*"); // Output of the following line: *abc * Console.WriteLine("*" + s2 + "*"); // Output of the following line: 4 Console.WriteLine(s2.Length);
字符串、扩展方法和 LINQ
由于 String 类型实现 IEnumerable<T>,因此可以对字符串使用 Enumerable 类中定义的扩展方法。 为了避免视觉干扰,这些方法已从 String 类型的 IntelliSense 中排除,但它们仍然可用。 此外,还可以使用字符串上的 LINQ 查询表达式。 有关详细信息,请参阅 LINQ 和字符串。
System.String 方法一览
新建
下表列出了返回新字符串对象的几个有用方法:
方法名称 | 使用 |
---|---|
String.Format | 从一组输入对象生成格式化的字符串。 |
String.Concat | 从两个或更多个字符串生成字符串。 |
String.Join | 通过合并字符串数组生成新字符串(需要指定分隔符)。 |
String.Insert | 通过将一个字符串插入现有字符串的指定索引处生成新字符串。 |
String.CopyTo | 将一个字符串中的指定字符复制到一个字符数组中的指定位置。 |
string greeting = "Hello World!"; char[] charArray = {'W','h','e','r','e'}; Console.WriteLine("The original character array: {0}", new string(charArray)); greeting.CopyTo(0, charArray,0 ,5); Console.WriteLine("The new character array: {0}", new string(charArray)); // The example displays the following output: // The original character array: Where // The new character array: Hello
删减
方法名称 | 使用 |
---|---|
String.Trim | 从字符串的开头和结尾移除空白或者指定的字符 |
String.TrimEnd | 从字符串的结尾移除在字符数组中指定的字符。 |
String.TrimStart | 从字符串的开头移除在字符数组中指定的字符。 |
String.Remove | 从字符串中的指定索引位置移除指定数量的字符。 |
string header = "* A Short String. *"; Console.WriteLine(header); Console.WriteLine(header.Trim( new Char[] { ' ', '*', '.' } )); // The example displays the following output: // * A Short String. * // A Short String ----------------------------------------------------------------------------- string MyString = "Hello, World!"; char[] MyChar = {'r','o','W','l','d','!',' '}; string NewString = MyString.TrimEnd(MyChar); Console.WriteLine(NewString); // Hello ----------------------------------------------------------------------------- string phrase = "a cold, dark night"; phrase = phrase.Replace(",", ""); // a cold dark night
更改
填充
方法名称 | 使用 |
---|---|
String.PadLeft | 使用前导字符将字符串填充到指定总长度。 |
String.PadRight | 使用尾随字符将字符串填充到指定总长度。 |
变更大小写
方法名称 | 使用 |
---|---|
String.ToUpper | 将字符串中的所有字符均转换为大写。 |
String.ToLower | 将字符串中的所有字符均转换为小写。 |
TextInfo.ToTitleCase | 将字符串转换为首字母大写。 |
其他详细内容,参考官方教程:
- 替换文本
- 替换匹配模式
- 修改单个字符
- 对字符串进行不安全修改
- 正则表达式
比较
方法名称 | 使用 |
---|---|
String.Compare | 比较两个字符串的值。 返回一个整数值。 |
String.CompareOrdinal | 比较两个字符串的值而不考虑本地区域性。 返回一个整数值。 |
String.CompareTo | 比较当前字符串对象和另一个字符串。 返回一个整数值。 |
String.StartsWith | 确定字符串是否以传递字的符串开头。 返回一个布尔值。 |
String.EndsWith | 确定字符串是否以传递的字符串结尾。 返回一个布尔值。 |
String.Equals | 确定两个字符串是否相同。 返回一个布尔值。 |
String.IndexOf | 返回字符或字符串的索引位置,从正在检查的字符串的开头开始。 返回一个整数值。 |
String.LastIndexOf | 返回字符或字符串的索引位置,从正在检查的字符串的结尾开始。 返回一个整数值。 |
注意:String.Compare 方法主要用于对字符串进行排序。 不应使用 String.Compare 方法来测试相等性(即,显式查找返回值 0 而不考虑一个字符串是否小于或大于另一个)。 相反,若要确定两个字符串是否相等,请使用 String.Equals() 方法。
更多的字符串比较,参考官方教程:
- 默认的序号比较
- 不区分大小写的序号比较
- 语义比较
- 使用特定区域性的比较
- 数组中的语义排序和字符串搜索
- 集合中的序号排序和搜索
- 引用相等性和字符串集中
拆分
Split(String[], Int32, StringSplitOptions) |
基于数组中的字符串将一个字符串拆分成最大数量的子字符串。 可以指定子字符串是否包含空数组元素。 |
Split(Char[], Int32, StringSplitOptions) |
基于数组中的字符将一个字符串拆分成最大数量的子字符串。 |
Split(String[], StringSplitOptions) |
基于数组中的字符串将字符串拆分为多个子字符串。 可以指定子字符串是否包含空数组元素。 |
Split(Char[]) |
基于数组中的字符将字符串拆分为多个子字符串。 |
Split(Char[], StringSplitOptions) |
基于数组中的字符将字符串拆分为多个子字符串。 可以指定子字符串是否包含空数组元素。 |
Split(Char[], Int32) |
基于数组中的字符将一个字符串拆分成最大数量的子字符串。 也可指定要返回的子字符串的最大数量。 |
string phrase = "The quick brown fox jumps over the lazy dog."; string[] words = phrase.Split(' ');
使用多个分隔符:
char[] delimiterChars = { ' ', ',', '.', ':', '\t' }; string text = "one\ttwo three:,four,\t:five six seven"; string[] words = text.Split(delimiterChars);
注意:任何分隔符的连续实例都会在输出数组中生成空字符串。
搜索
public bool String.Contains (string value);
使用 StringBuilder
.NET 中的字符串操作进行了高度的优化,在大多数情况下不会显著影响性能。 但是,在某些情况下(例如,执行数百次或数千次的紧密循环),字符串操作可能影响性能。 StringBuilder 类创建字符串缓冲区,用于在程序执行多个字符串操控时提升性能。 使用 StringBuilder 字符串,还可以重新分配各个字符,而内置字符串数据类型则不支持这样做。
System.Text.StringBuilder sb = new System.Text.StringBuilder(); // Create a string composed of numbers 0 - 9 for (int i = 0; i < 10; i++) { sb.Append(i.ToString()); } System.Console.WriteLine(sb); // displays 0123456789 // Copy one character of the string (not possible with a System.String) sb[0] = sb[9]; System.Console.WriteLine(sb); // displays 9123456789
方法名称使用String.Format从一组输入对象生成格式化的字符串。String.Concat从两个或更多个字符串生成字符串。String.Join通过合并字符串数组生成新字符串。String.Insert通过将一个字符串插入现有字符串的指定索引处生成新字符串。String.CopyTo将一个字符串中的指定字符复制到一个字符数组中的指定位置。
设置容量和长度
虽然 StringBuilder 是动态对象,支持扩展它封装的字符串中的字符数,但可以指定值,作为对象可保留的字符数上限。此值称为“对象容量”。修改 StringBuilder 时,除非达到容量,否则对象不会为自己重新分配空间。 当达到容量时,将自动分配新的空间且容量翻倍。 可以使用重载的构造函数之一,指定 StringBuilder 类的容量。 也可以使用读/写 Capacity 属性,设置对象的长度上限。
EnsureCapacity 方法可用于检查当前 StringBuilder 的容量。 如果容量大于传递的值,则不进行任何更改;但是,如果容量小于传递的值,则会更改当前的容量以使其与传递的值匹配。
也可以查看或设置 Length 属性。 如果将 Length 属性设置为大于 Capacity 属性的值,则自动将 Capacity 属性更改为与 Length 属性相同的值。 如果将 Length 属性设置为小于当前 StringBuilder 对象内的字符串长度的值,则会缩短该字符串。
修改 StringBuilder 字符串
下表列出了可用于修改 StringBuilder 内容的方法:
方法名称 | 使用 |
---|---|
StringBuilder.Append | 将信息追加到当前 StringBuilder 的末尾。 |
StringBuilder.AppendFormat | 用带格式文本替换字符串中传递的格式说明符。 |
StringBuilder.Insert | 将字符串或对象插入到当前 StringBuilder 的指定索引中。 |
StringBuilder.Remove | 从当前 StringBuilder 中删除指定数量的字符。 |
StringBuilder.Replace | 替换指定索引处的指定字符。 |
将 StringBuilder 对象转换为字符串
必须先将 StringBuilder 对象转换为 String 对象,然后才能将 StringBuilder 对象表示的字符串传递给包含 String 参数的方法,或在用户界面中显示它。 可通过调用 StringBuilder.ToString 方法来执行此转换。 下面的示例先调用许多 StringBuilder 方法,再调用 StringBuilder.ToString() 方法来显示字符串。
StringBuilder sb = new StringBuilder(); bool flag = true; string[] spellings = { "recieve", "receeve", "receive" }; sb.AppendFormat("Which of the following spellings is {0}:", flag); sb.AppendLine(); for (int ctr = 0; ctr <= spellings.GetUpperBound(0); ctr++) { sb.AppendFormat(" {0}. {1}", ctr, spellings[ctr]); sb.AppendLine(); } sb.AppendLine(); Console.WriteLine(sb.ToString()); // The example displays the following output: // Which of the following spellings is True: // 0. recieve // 1. receeve // 2. receive
.NET 中的字符编码
- .NET 中的编码
- 选择编码类
- 使用编码对象
- 选择回退策略
- 实现自定义回退策略