System.String 类
方法描述
表示文本,即一系列 Unicode 字符。
语法定义(C# System.String 类 的用法)
[SerializableAttribute] [ComVisibleAttribute(true)] public sealed class String : IComparable, ICloneable, IConvertible, IComparable, IEnumerable , IEnumerable, IEquatable
构造函数
构造函数名称 | 构造函数描述 |
---|---|
String(Char*) | 将 String 类的新实例初始化为由指向 Unicode 字符数组的指定指针指示的值。 |
String(Char[]) | 将 String 类的新实例初始化为由 Unicode 字符数组指示的值。 |
String(SByte*) | 将 String 类的新实例初始化为由指向 8 位带符号整数数组的指针指示的值。 |
String(Char, Int32) | 将 String 类的新实例初始化为由重复指定次数的指定 Unicode 字符指示的值。 |
String(Char*, Int32, Int32) | 将 String 类的新实例初始化为由指向 Unicode 字符数组的指定指针、该数组内的起始字符位置和一个长度指示的值。 |
String(Char[], Int32, Int32) | 将 String 类的新实例初始化为由 Unicode 字符数组、该数组内的起始字符位置和一个长度指示的值。 |
String(SByte*, Int32, Int32) | 将 String 类的新实例初始化为由指向 8 位带符号整数数组的指定指针、该数组内的起始字符位置和一个长度指示的值。 |
String(SByte*, Int32, Int32, Encoding) | 将 String 类的新实例初始化为由指向 8 位带符号整数数组的指定指针、该数组内的起始字符位置、长度以及 Encoding 对象指示的值。 |
成员/方法
方法名称 | 方法描述 |
---|---|
Clone | 返回对此 String 实例的引用。 |
Compare(String, String) | 比较两个指定的 String 对象,并返回一个整数,指示二者在排序顺序中的相对位置。 |
Compare(String, String, Boolean) | 比较两个指定的 String 对象(其中忽略或考虑其大小写),并返回一个整数,指示二者在排序顺序中的相对位置。 |
Compare(String, String, StringComparison) | 使用指定的规则比较两个指定的 String 对象,并返回一个整数,指示二者在排序顺序中的相对位置。 |
Compare(String, String, Boolean, CultureInfo) | 比较两个指定的 String 对象(其中忽略或考虑其大小写,并使用区域性特定的信息干预比较),并返回一个整数,指示二者在排序顺序中的相对位置。 |
Compare(String, String, CultureInfo, CompareOptions) | 对两个指定的 String 对象进行比较,使用指定的比较选项和区域性特定的信息来影响比较,并返回一个整数,该整数指示这两个字符串在排序顺序中的关系。 |
Compare(String, Int32, String, Int32, Int32) | 对两个指定的 String 对象的子字符串进行比较,并返回一个指示二者在排序顺序中的相对位置的整数。 |
Compare(String, Int32, String, Int32, Int32, Boolean) | 比较两个指定的 String 对象的子字符串(忽略或考虑其大小写),并返回一个整数,指示二者在排序顺序中的相对位置。 |
Compare(String, Int32, String, Int32, Int32, StringComparison) | 使用指定的规则比较两个指定的 String 对象的子字符串,并返回一个整数,指示二者在排序顺序中的相对位置。 |
Compare(String, Int32, String, Int32, Int32, Boolean, CultureInfo) | 比较两个指定的 String 对象的子字符串(其中忽略或考虑其大小写,并使用区域性特定的信息干预比较),并返回一个整数,指示二者在排序顺序中的相对位置。 |
Compare(String, Int32, String, Int32, Int32, CultureInfo, CompareOptions) | 对两个指定 String 对象的子字符串进行比较,使用指定的比较选项和区域性特定的信息来影响比较,并返回一个整数,该整数指示这两个子字符串在排序顺序中的关系。 |
CompareOrdinal(String, String) | 通过计算每个字符串中相应 Char 对象的数值来比较两个指定的 String 对象。 |
CompareOrdinal(String, Int32, String, Int32, Int32) | 通过计算两个指定的 String 对象的每个子字符串中相应 Char 对象的数值比较子字符串。 |
CompareTo(Object) | 将此实例与指定的 Object 进行比较,并指示此实例在排序顺序中是位于指定的 Object 之前、之后还是与其出现在同一位置。 |
CompareTo(String) | 将此实例与指定的 String 对象进行比较,并指示此实例在排序顺序中是位于指定的 String 之前、之后还是与其出现在同一位置。 |
Concat(Object) | 创建指定对象的字符串表示形式。 |
Concat(Object[]) | 连接指定 Object 数组中的元素的字符串表示形式。 |
Concat(IEnumerable |
串联类型为 String 的 IEnumerable |
Concat(String[]) | 连接指定的 String 数组的元素。 |
Concat(Object, Object) | 连接两个指定对象的字符串表示形式。 |
Concat(String, String) | 连接 String 的两个指定实例。 |
Concat(Object, Object, Object) | 连接三个指定对象的字符串表示形式。 |
Concat(String, String, String) | 连接 String 的三个指定实例。 |
Concat(Object, Object, Object, Object) | 将四个指定对象的字符串表示形式与可选变量长度参数列表中指定的任何对象串联起来。 |
Concat(String, String, String, String) | 连接 String 的四个指定实例。 |
Concat |
串联 IEnumerable |
Contains | 返回一个值,该值指示指定的 String 对象是否出现在此字符串中。 |
Copy | 创建一个与指定的 String 具有相同值的 String 的新实例。 |
CopyTo | 将指定数目的字符从此实例中的指定位置复制到 Unicode 字符数组中的指定位置。 |
EndsWith(String) | 确定此字符串实例的结尾是否与指定的字符串匹配。 |
EndsWith(String, StringComparison) | 确定使用指定的比较选项进行比较时此字符串实例的结尾是否与指定的字符串匹配。 |
EndsWith(String, Boolean, CultureInfo) | 确定在使用指定的区域性进行比较时此字符串实例的结尾是否与指定的字符串匹配。 |
Equals(Object) | 确定此实例是否与指定的对象(也必须是 String 对象)具有相同的值。 (重写 Object.Equals(Object)。) |
Equals(String) | 确定此实例是否与另一个指定的 String 对象具有相同的值。 |
Equals(String, String) | 确定两个指定的 String 对象是否具有相同的值。 |
Equals(String, StringComparison) | 确定此字符串是否与指定的 String 对象具有相同的值。 参数指定区域性、大小写以及比较所用的排序规则。 |
Equals(String, String, StringComparison) | 确定两个指定的 String 对象是否具有相同的值。 参数指定区域性、大小写以及比较所用的排序规则。 |
Finalize | 允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。 (继承自 Object。) |
Format(String, Object) | 将指定字符串中的一个或多个格式项替换为指定对象的字符串表示形式。 |
Format(String, Object[]) | 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。 |
Format(IFormatProvider, String, Object[]) | 将指定字符串中的格式项替换为指定数组中相应对象的字符串表示形式。 指定的参数提供区域性特定的格式设置信息。 |
Format(String, Object, Object) | 将指定字符串中的格式项替换为两个指定对象的字符串表示形式。 |
Format(String, Object, Object, Object) | 将指定字符串中的格式项替换为三个指定对象的字符串表示形式。 |
GetEnumerator | 检索一个可以循环访问此字符串中的每个字符的对象。 |
GetHashCode | 返回该字符串的哈希代码。 (重写 Object.GetHashCode()。) |
GetType | 获取当前实例的 Type。 (继承自 Object。) |
GetTypeCode | 返回类 String 的 TypeCode。 |
IndexOf(Char) | 报告指定 Unicode 字符在此字符串中的第一个匹配项的索引。 |
IndexOf(String) | 报告指定字符串在此实例中的第一个匹配项的索引。 |
IndexOf(Char, Int32) | 报告指定 Unicode 字符在此字符串中的第一个匹配项的索引。 该搜索从指定字符位置开始。 |
IndexOf(String, Int32) | 报告指定字符串在此实例中的第一个匹配项的索引。 该搜索从指定字符位置开始。 |
IndexOf(String, StringComparison) | 报告指定的字符串在当前 String 对象中的第一个匹配项的索引。 一个参数指定要用于指定字符串的搜索类型。 |
IndexOf(Char, Int32, Int32) | 报告指定字符在此实例中的第一个匹配项的索引。 搜索从指定字符位置开始,并检查指定数量的字符位置。 |
IndexOf(String, Int32, Int32) | 报告指定字符串在此实例中的第一个匹配项的索引。 搜索从指定字符位置开始,并检查指定数量的字符位置。 |
IndexOf(String, Int32, StringComparison) | 报告指定的字符串在当前 String 对象中的第一个匹配项的索引。 参数指定当前字符串中的起始搜索位置以及用于指定字符串的搜索类型。 |
IndexOf(String, Int32, Int32, StringComparison) | 报告指定的字符串在当前 String 对象中的第一个匹配项的索引。 参数指定当前字符串中的起始搜索位置、要搜索的当前字符串中的字符数量,以及要用于指定字符串的搜索类型。 |
IndexOfAny(Char[]) | 报告指定 Unicode 字符数组中的任意字符在此实例中第一个匹配项的索引。 |
IndexOfAny(Char[], Int32) | 报告指定 Unicode 字符数组中的任意字符在此实例中第一个匹配项的索引。 该搜索从指定字符位置开始。 |
IndexOfAny(Char[], Int32, Int32) | 报告指定 Unicode 字符数组中的任意字符在此实例中第一个匹配项的索引。 搜索从指定字符位置开始,并检查指定数量的字符位置。 |
Insert | 在此实例中的指定索引位置插入一个指定的 String 实例。 |
Intern | 检索系统对指定 String 的引用。 |
IsInterned | 检索对指定 String 的引用。 |
IsNormalized() | 指示此字符串是否符合 Unicode 范式 C。 |
IsNormalized(NormalizationForm) | 指示此字符串是否符合指定的 Unicode 范式。 |
IsNullOrEmpty | 指示指定的字符串是 null 还是 Empty 字符串。 |
IsNullOrWhiteSpace | 指示指定的字符串是 null、空还是仅由空白字符组成。 |
Join(String, IEnumerable |
串联类型为 String 的 IEnumerable |
Join(String, Object[]) | 串联对象数组的各个元素,其中在每个元素之间使用指定的分隔符。 |
Join(String, String[]) | 串联字符串数组的所有元素,其中在每个元素之间使用指定的分隔符。 |
Join(String, String[], Int32, Int32) | 串联字符串数组的指定元素,其中在每个元素之间使用指定的分隔符。 |
Join |
串联集合的成员,其中在每个成员之间使用指定的分隔符。 |
LastIndexOf(Char) | 报告指定 Unicode 字符在此实例中的最后一个匹配项的索引位置。 |
LastIndexOf(String) | 报告指定字符串在此实例中的最后一个匹配项的索引位置。 |
LastIndexOf(Char, Int32) | 报告指定 Unicode 字符在此实例中的最后一个匹配项的索引位置。 该搜索从指定字符位置开始。 |
LastIndexOf(String, Int32) | 报告指定字符串在此实例中的最后一个匹配项的索引位置。 该搜索从指定字符位置开始。 |
LastIndexOf(String, StringComparison) | 报告指定字符串在当前 String 对象中最后一个匹配项的索引。 一个参数指定要用于指定字符串的搜索类型。 |
LastIndexOf(Char, Int32, Int32) | 报告指定的 Unicode 字符在此实例内的子字符串中的最后一个匹配项的索引位置。 搜索从指定字符位置开始,并检查指定数量的字符位置。 |
LastIndexOf(String, Int32, Int32) | 报告指定字符串在此实例中的最后一个匹配项的索引位置。 搜索从指定字符位置开始,并检查指定数量的字符位置。 |
LastIndexOf(String, Int32, StringComparison) | 报告指定字符串在当前 String 对象中最后一个匹配项的索引。 参数指定当前字符串中的起始搜索位置,以及要用于指定字符串的搜索类型。 |
LastIndexOf(String, Int32, Int32, StringComparison) | 报告指定字符串在此实例中的最后一个匹配项的索引位置。 参数指定当前字符串中的起始搜索位置、要搜索的当前字符串中的字符数量,以及要用于指定字符串的搜索类型。 |
LastIndexOfAny(Char[]) | 报告在 Unicode 数组中指定的一个或多个字符在此实例中的最后一个匹配项的索引位置。 |
LastIndexOfAny(Char[], Int32) | 报告在 Unicode 数组中指定的一个或多个字符在此实例中的最后一个匹配项的索引位置。 该搜索从指定字符位置开始。 |
LastIndexOfAny(Char[], Int32, Int32) | 报告在 Unicode 数组中指定的一个或多个字符在此实例中的最后一个匹配项的索引位置。 搜索从指定字符位置开始,并检查指定数量的字符位置。 |
MemberwiseClone | 创建当前 Object 的浅表副本。 (继承自 Object。) |
Normalize() | 返回一个新字符串,其文本值与此字符串相同,但其二进制表示形式符合 Unicode 范式 C。 |
Normalize(NormalizationForm) | 返回一个新字符串,其文本值与此字符串相同,但其二进制表示形式符合指定的 Unicode 范式。 |
PadLeft(Int32) | 返回一个新字符串,该字符串通过在此实例中的字符左侧填充空格来达到指定的总长度,从而实现右对齐。 |
PadLeft(Int32, Char) | 返回一个新字符串,该字符串通过在此实例中的字符左侧填充指定的 Unicode 字符来达到指定的总长度,从而使这些字符右对齐。 |
PadRight(Int32) | 返回一个新字符串,该字符串通过在此字符串中的字符右侧填充空格来达到指定的总长度,从而使这些字符左对齐。 |
PadRight(Int32, Char) | 返回一个新字符串,该字符串通过在此字符串中的字符右侧填充指定的 Unicode 字符来达到指定的总长度,从而使这些字符左对齐。 |
Remove(Int32) | 删除此字符串中从指定位置到最后位置的所有字符。 |
Remove(Int32, Int32) | 从此实例中的指定位置开始删除指定数目的字符。 |
Replace(Char, Char) | 返回一个新字符串,其中此实例中出现的所有指定 Unicode 字符都替换为另一个指定的 Unicode 字符。 |
Replace(String, String) | 返回一个新字符串,其中当前实例中出现的所有指定字符串都替换为另一个指定的字符串。 |
Split(Char[]) | 返回的字符串数组包含此实例中的子字符串(由指定 Unicode 字符数组的元素分隔)。 |
Split(Char[], Int32) | 返回的字符串数组包含此实例中的子字符串(由指定 Unicode 字符数组的元素分隔)。 参数指定返回的子字符串的最大数量。 |
Split(Char[], StringSplitOptions) | 返回的字符串数组包含此字符串中的子字符串(由指定 Unicode 字符数组的元素分隔)。 参数指定是否返回空数组元素。 |
Split(String[], StringSplitOptions) | 返回的字符串数组包含此字符串中的子字符串(由指定字符串数组的元素分隔)。 参数指定是否返回空数组元素。 |
Split(Char[], Int32, StringSplitOptions) | 返回的字符串数组包含此字符串中的子字符串(由指定 Unicode 字符数组的元素分隔)。 参数指定要返回子字符串的最大数量,以及是否返回空数组元素。 |
Split(String[], Int32, StringSplitOptions) | 返回的字符串数组包含此字符串中的子字符串(由指定字符串数组的元素分隔)。 参数指定要返回子字符串的最大数量,以及是否返回空数组元素。 |
StartsWith(String) | 确定此字符串实例的开头是否与指定的字符串匹配。 |
StartsWith(String, StringComparison) | 确定在使用指定的比较选项进行比较时此字符串实例的开头是否与指定的字符串匹配。 |
StartsWith(String, Boolean, CultureInfo) | 确定在使用指定的区域性进行比较时此字符串实例的开头是否与指定的字符串匹配。 |
Substring(Int32) | 从此实例检索子字符串。 子字符串从指定的字符位置开始。 |
Substring(Int32, Int32) | 从此实例检索子字符串。 子字符串从指定的字符位置开始且具有指定的长度。 |
ToCharArray() | 将此实例中的字符复制到 Unicode 字符数组。 |
ToCharArray(Int32, Int32) | 将此实例中的指定子字符串内的字符复制到 Unicode 字符数组。 |
ToLower() | 返回此字符串转换为小写形式的副本。 |
ToLower(CultureInfo) | 根据指定区域性的大小写规则返回此字符串转换为小写形式的副本。 |
ToLowerInvariant | 返回此 String 对象的转换为小写形式的副本,返回时使用固定区域性的大小写规则。 |
ToString() | 返回 String 的此实例;不执行实际转换。 (重写 Object.ToString()。) |
ToString(IFormatProvider) | 返回 String 的此实例;不执行实际转换。 |
ToUpper() | 返回此字符串转换为大写形式的副本。 |
ToUpper(CultureInfo) | 根据指定区域性的大小写规则返回此字符串转换为大写形式的副本。 |
ToUpperInvariant | 返回此 String 对象的转换为大写形式的副本,返回时使用固定区域性的大小写规则。 |
Trim() | 从当前 String 对象移除所有前导空白字符和尾部空白字符。 |
Trim(Char[]) | 从当前 String 对象移除数组中指定的一组字符的所有前导匹配项和尾部匹配项。 |
TrimEnd | 从当前 String 对象移除数组中指定的一组字符的所有尾部匹配项。 |
TrimStart | 从当前 String 对象移除数组中指定的一组字符的所有前导匹配项。 |
提示和注释
字符串是 Unicode 字符的有序集合,用于表示文本。 String 对象是 System.Char 对象的有序集合,用于表示字符串。 String 对象的值是该有序集合的内容,并且该值是不可变的(即,为只读)。 有关字符串的不变性的更多信息,请参见 不变性和 StringBuilder 类 部分。
本部分的引用包括以下信息:
实例化 String 对象
Char 对象和 Unicode 字符
字符串和嵌入的 Null 字符
字符串和索引
Null 字符串和空字符串
不变性和 StringBuilder 类
序号与 区分区域性的操作
正常化
按类别划分的字符串操作
实例化 String 对象
可以通过以下方式实例化 String 对象:
通过把字符串文字分配到 String 变量。 这是用于创建一个字符串最常用的方法。 下面的示例利用赋值创建多个字符串。 请注意,在 C# 中,由于反斜杠 (\) 是个转义字符,所以必须转义字符串中的反斜杠,或者必须给整个字符串加上 @ 前缀。
C#
VB
复制
string string1 = "This is a string created by assignment.";
Console.WriteLine(string1);
string string2a = "The path is C:\\PublicDocuments\\Report1.doc";
Console.WriteLine(string2a);
string string2b = @"The path is C:\PublicDocuments\Report1.doc";
Console.WriteLine(string2b);
// The example displays the following output:
// This is a string created by assignment.
// The path is C:\PublicDocuments\Report1.doc
// The path is C:\PublicDocuments\Report1.doc
通过调用 String 类构造函数。 下面的示例通过调用几个类构造函数实例化字符串。 请注意,一些构造函数的参数包括指向字符数组或带符号的字节数组的指针。 Visual Basic 不支持对这些构造函数的调用。
C#
VB
复制
char[] chars = { 'w', 'o', 'r', 'd' };
sbyte[] bytes = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x00 };
// Create a string from a character array.
string string1 = new string(chars);
Console.WriteLine(string1);
// Create a string that consists of a character repeated 20 times.
string string2 = new string('c', 20);
Console.WriteLine(string2);
string stringFromBytes = null;
string stringFromChars = null;
unsafe
{
fixed (sbyte* pbytes = bytes)
{
// Create a string from a pointer to a signed byte array.
stringFromBytes = new string(pbytes);
}
fixed (char* pchars = chars)
{
// Create a string from a pointer to a character array.
stringFromChars = new string(pchars);
}
}
Console.WriteLine(stringFromBytes);
Console.WriteLine(stringFromChars);
// The example displays the following output:
// word
// cccccccccccccccccccc
// ABCDE
// word
通过使用字符串串联运算符(+ 在 C# 中,& 或 + 在 Visual Basic 中)以根据 String 实例和字符串文本的任意组合来创建单个字符串。 下面的示例演示了字符串串联运算符的用法。
C#
VB
复制
string string1 = "Today is " + DateTime.Now.ToString("D") + ".";
Console.WriteLine(string1);
string string2 = "This is one sentence. " + "This is a second. ";
string2 += "This is a third sentence.";
Console.WriteLine(string2);
// The example displays output like the following:
// Today is Tuesday, July 06, 2011.
// This is one sentence. This is a second. This is a third sentence.
通过检索属性或调用返回字符串的方法。 下面的示例使用 String 类的方法以提取来自较大字符串的子字符串。
C#
VB
复制
string sentence = "This sentence has five words.";
// Extract the second word.
int startPosition = sentence.IndexOf(" ") + 1;
string word2 = sentence.Substring(startPosition,
sentence.IndexOf(" ", startPosition) - startPosition);
Console.WriteLine("Second word: " + word2);
// The example displays the following output:
// Second word: sentence
通过调用格式方法把值或对象转换为字符串表示形式。 下面的示例使用 复合格式 功能将两个对象的字符串表示形式嵌入到字符串。
C#
VB
复制
DateTime dateAndTime = new DateTime(2011, 7, 6, 7, 32, 0);
double temperature = 68.3;
string result = String.Format("At {0:t} on {0:D}, the temperature was {1:F1} degrees Fahrenheit.",
dateAndTime, temperature);
Console.WriteLine(result);
// The example displays the following output:
// At 7:32 AM on Wednesday, July 06, 2011, the temperature was 68.3 degrees Fahrenheit.
返回备注
Char 对象和 Unicode 字符
字符串中的每个字符都是由 Unicode 标量值定义的,Unicode 标量值也称为 Unicode 码位或者 Unicode 字符的序号(数字)值。 每个码位都是使用 UTF-16 编码进行编码的,编码的每个元素的数值都用一个 Char 对象表示。
一个 Char 对象通常表示一个码位,即:Char 的数值等于该码位。 例如,字符“a”的码位为 U+0061。 但是,一个码位可能需要多个编码元素(多个 Char 对象)。 Unicode 标准定义了三种类型的字符,对应多个 Char 对象:字母 、Unicode 补充代码点和辅助平面中的字符。
字素由后跟一个或多个组合字符的基本字符表示。 例如,字符 ä 由码位为 U+0061 的 Char 对象表示,该对象后接码位为 U+0308 的 Char 对象。 具有 U + 00E4 代码点的单个 Char 对象也可以定义此字符。 如下示例所示,平等的区分区域性的比较表明虽然普通的序号比较不是平等的,但这两种表示形式是。 但是,如果这两个字符串均正常化,则序号比较还表示它们相等。 (有关正常化字符串的更多信息,请参见 Normalization 部分。)
C#
VB
复制
using System;
using System.Globalization;
using System.IO;
public class Example
{
public static void Main()
{
StreamWriter sw = new StreamWriter(@".\graphemes.txt");
string grapheme = "\u0061\u0308";
sw.WriteLine(grapheme);
string singleChar = "\u00e4";
sw.WriteLine(singleChar);
sw.WriteLine("{0} = {1} (Culture-sensitive): {2}", grapheme, singleChar,
String.Equals(grapheme, singleChar,
StringComparison.CurrentCulture));
sw.WriteLine("{0} = {1} (Ordinal): {2}", grapheme, singleChar,
String.Equals(grapheme, singleChar,
StringComparison.Ordinal));
sw.WriteLine("{0} = {1} (Normalized Ordinal): {2}", grapheme, singleChar,
String.Equals(grapheme.Normalize(),
singleChar.Normalize(),
StringComparison.Ordinal));
sw.Close();
}
}
// The example produces the following output:
// ä
// ä
// ä = ä (Culture-sensitive): True
// ä = ä (Ordinal): False
// ä = ä (Normalized Ordinal): True
Unicode 补充码位(一个代理项对)由 Char 对象表示,该对象的码位为高代理项,其后跟着码位是低代理项的 Char 对象。 高代理项的码位的范围是从 U + D800 到 U + DBFF。 低代理项的码位的范围是从 U + DC00 到 U + DFFF。 代理项对用于表示 16 Unicode 辅助平面中的字符。 下面的示例创建代理项字符,并将它传递到 Char.IsSurrogatePair(Char, Char) 方法以确定其是否为代理项对。
C#
VB
复制
using System;
public class Example
{
public static void Main()
{
string surrogate = "\uD800\uDC03";
for (int ctr = 0; ctr < surrogate.Length; ctr++)
Console.Write("U+{0:X2} ", Convert.ToUInt16(surrogate[ctr]));
Console.WriteLine();
Console.WriteLine(" Is Surrogate Pair: {0}",
Char.IsSurrogatePair(surrogate[0], surrogate[1]));
}
}
// The example displays the following output:
// U+D800 U+DC03
// Is Surrogate Pair: True
返回备注
字符串和嵌入的 Null 字符
在 .NET Framework 中,String 对象可以包含嵌入的 null 字符,这些值将算作字符串长度的一部分。 但是,在某些语言(例如 C 和 C++)中,null 字符指示字符串的结尾;不会将其视为字符串的一部分,并且将不算作字符串长度的一部分。 这意味着当应用于 String 对象时,C 和 C++ 程序员或使用 C 或 C++ 编写的库对字符串作出的下列常规假设不一定有效:
strlen 或 wcslen 函数返回的值不一定等于 String.Length。
由 strcpy_s 或 wcscpy_s 函数创建的字符串不一定与通过 String.Copy 方法创建的字符串相同。
应确保对 String 对象进行实例化的本机 C 和 C++ 代码以及通过平台调用传递 String 对象的代码不假设使用嵌入的 null 字符标记字符串的结尾。
在排序(或比较)字符串时以及搜索字符串时,也将以不同的方式处理嵌入的 null 字符。 在两个字符串之间执行区分区域性的比较时忽略 Null 字符,包括使用固定区域性的比较。 仅在进行序号或不区分大小写的序号比较时考虑它们。 另一方面,在使用 Contains、StartsWith 和 IndexOf 等方法搜索字符串时,始终考虑嵌入的 NULL 字符串。
返回备注
字符串和索引
索引是 Char 对象在 String 中的位置(而不是 Unicode 字符的位置)。 索引是从零开始、从字符串的起始位置(其索引为零)计起的非负数字。 一些搜索方法,例如 IndexOf 和 LastIndexOf 返回字符串实例中的字符或子字符串的索引。
Chars 属性可让您按其在字符串中的索引位置访问各个 Char 对象。 因为 Chars 属性为(在 Visual Basic 中的)默认属性或索引器(在 C# 中),所以可使用如下代码在字符串中访问单个 Char 对象。 此代码查找字符串中的空白或标点字符,以确定该字符串包含多少字。
C#
VB
复制
using System;
public class Example
{
public static void Main()
{
string s1 = "This string consists of a single short sentence.";
int nWords = 0;
s1 = s1.Trim();
for (int ctr = 0; ctr < s1.Length; ctr++) {
if (Char.IsPunctuation(s1[ctr]) | Char.IsWhiteSpace(s1[ctr]))
nWords++;
}
Console.WriteLine("The sentence\n {0}\nhas {1} words.",
s1, nWords);
}
}
// The example displays the following output:
// The sentence
// This string consists of a single short sentence.
// has 8 words.
如下示例所示,因为 String 类实现 IEnumerable 接口,所以还可以使用 foreach 构造在字符串中通过 Char 对象进行循环访问。
C#
VB
复制
using System;
public class Example
{
public static void Main()
{
string s1 = "This string consists of a single short sentence.";
int nWords = 0;
s1 = s1.Trim();
foreach (var ch in s1) {
if (Char.IsPunctuation(ch) | Char.IsWhiteSpace(ch))
nWords++;
}
Console.WriteLine("The sentence\n {0}\nhas {1} words.",
s1, nWords);
}
}
// The example displays the following output:
// The sentence
// This string consists of a single short sentence.
// has 8 words.
连续的索引值可能并不与连续的 Unicode 字符相对应,这是因为一个 Unicode 字符可能会编码为多个 Char 对象。 为了使用 Unicode 字符而不是 Char 对象,可使用 System.Globalization.StringInfo 和 TextElementEnumerator 类。 下面的示例演示了使用 Char 对象和使用 Unicode 字符的代码之间的区别。 它比较句子的每个单词中字符或文本元素的数目。 该字符串包括两个基字符序列,后接组合字符。
C#
VB
复制
using System;
using System.Collections.Generic;
using System.Globalization;
public class Example
{
public static void Main()
{
// First sentence of The Mystery of the Yellow Room, by Leroux.
string opening = "Ce n'est pas sans une certaine émotion que "+
"je commence à raconter ici les aventures " +
"extraordinaires de Joseph Rouletabille.";
// Character counters.
int nChars = 0;
// Objects to store word count.
List
List
foreach (var ch in opening) {
// Skip the ' character.
if (ch == '\u0027') continue;
if (Char.IsWhiteSpace(ch) | (Char.IsPunctuation(ch))) {
chars.Add(nChars);
nChars = 0;
}
else {
nChars++;
}
}
TextElementEnumerator te = StringInfo.GetTextElementEnumerator(opening);
while (te.MoveNext()) {
string s = te.GetTextElement();
// Skip the ' character.
if (s == "\u0027") continue;
if ( String.IsNullOrEmpty(s.Trim()) | (s.Length == 1 && Char.IsPunctuation(Convert.ToChar(s)))) {
elements.Add(nChars);
nChars = 0;
}
else {
nChars++;
}
}
// Display character counts.
Console.WriteLine("{0,6} {1,20} {2,20}",
"Word #", "Char Objects", "Characters");
for (int ctr = 0; ctr < chars.Count; ctr++)
Console.WriteLine("{0,6} {1,20} {2,20}",
ctr, chars[ctr], elements[ctr]);
}
}
// The example displays the following output:
// Word # Char Objects Characters
// 0 2 2
// 1 4 4
// 2 3 3
// 3 4 4
// 4 3 3
// 5 8 8
// 6 8 7
// 7 3 3
// 8 2 2
// 9 8 8
// 10 2 1
// 11 8 8
// 12 3 3
// 13 3 3
// 14 9 9
// 15 15 15
// 16 2 2
// 17 6 6
// 18 12 12
返回备注
Null 字符串和空字符串
已声明但尚未分配值的字符串为 null。 尝试对该字符串调用方法引出 NullReferenceException。 空字符串是不同于空的字符串,是其值为“”或 String.Empty 的字符串。 在某些情况下,将 null 字符串或空字符串作为参数传递给方法将引发异常。 例如,把 Null 字符串传递到 Int32.Parse 方法将引出 ArgumentNullException,传递空字符串将引出 FormatException。 在其他情况下,方法参数可以为 null 字符串或空字符串。 例如,要提供类的 IFormattable 实现,则需要用常规(“G”)格式指示符使 Null 字符串等同于空字符串。
String 类包括以下两种方便的方法,使您能够测试字符串是否为 null 或为空:
IsNullOrEmpty ,指示字符串是否为 null 或等于 String.Empty。 该方法消除了使用如下代码的需要:
C#
VB
复制
if (str == null || str.Equals(String.Empty))
IsNullOrWhiteSpace ,指示字符串是否为 null,等于 String.Empty,或仅由空白字符组成。 该方法消除了使用如下代码的需要:
C#
VB
复制
if (str == null || str.Equals(String.Empty) || str.Trim().Equals(String.Empty))
下面的示例使用自定义 Temperature 类的 IFormattable.ToString 实现中的 IsNullOrEmpty 方法。 该方法支持"G"、"C"、"F"和"K" 格式字符串。 如将空格式字符串或值为 null 的格式字符串传递到该方法,则其值更改为“G”格式字符串。
C#
VB
复制
public string ToString(string format, IFormatProvider provider)
{
if (String.IsNullOrEmpty(format)) format = "G";
if (provider == null) provider = CultureInfo.CurrentCulture;
switch (format.ToUpperInvariant())
{
// Return degrees in Celsius.
case "G":
case "C":
return temp.ToString("F2", provider) + "°C";
// Return degrees in Fahrenheit.
case "F":
return (temp * 9 / 5 + 32).ToString("F2", provider) + "°F";
// Return degrees in Kelvin.
case "K":
return (temp + 273.15).ToString();
default:
throw new FormatException(
String.Format("The {0} format string is not supported.",
format));
}
}
返回备注
不变性和 StringBuilder 类
String 对象称为不可变的(只读),因为在创建了该对象之后,就不能修改该对象的值。 看来似乎修改了 String 对象的方法实际上是返回一个包含修改内容的新 String 对象。
因为字符串是不可变的,所以对单个字符串执行字符串加法或减法操作时可以减少重大性能损失。 例如,以下代码使用随机数字生成器来创建含有在 0x0001 到 0x052F 范围之间的 1000 个字符的字符串。 尽管该代码会出现以使用字符串串联来将新的字符追加到命名为 str 的现有字符串,它实际上会为每个串联操作创建新的 String 对象。
C#
VB
复制
using System;
using System.IO;
using System.Text;
public class Example
{
public static void Main()
{
Random rnd = new Random();
string str = String.Empty;
StreamWriter sw = new StreamWriter(@".\StringFile.txt",
false, Encoding.Unicode);
for (int ctr = 0; ctr <= 1000; ctr++) {
str += Convert.ToChar(rnd.Next(1, 0x0530));
if (str.Length % 60 == 0)
str += Environment.NewLine;
}
sw.Write(str);
sw.Close();
}
}
可使用 StringBuilder 类代替 String 类多次更改字符串值。 不同于 String 类的实例,StringBuilder 对象是可变的;当您串联、 追加或删除字符串中的子字符串,则会对单个字符串执行操作。 完成 StringBuilder 对象的值的修改后,可以调用其 StringBuilder.ToString 方法将其转换为字符串。 下面的示例将替换用在前面示例中的 String 以连接从 0x0001 到 0x052F 范围内并带 StringBuilder 对象的 1000 个随机字符。
C#
VB
复制
using System;
using System.IO;
using System.Text;
public class Example
{
public static void Main()
{
Random rnd = new Random();
StringBuilder sb = new StringBuilder();
StreamWriter sw = new StreamWriter(@".\StringFile.txt",
false, Encoding.Unicode);
for (int ctr = 0; ctr <= 1000; ctr++) {
sb.Append(Convert.ToChar(rnd.Next(1, 0x0530)));
if (sb.Length % 60 == 0)
sb.AppendLine();
}
sw.Write(sb.ToString());
sw.Close();
}
}
返回备注
序号与区分区域性的操作
String 类的成员对 String 对象执行序号操作或区分区域性(语言)操作。 序号运算是对每个 Char 对象的数值执行的。 区分区域性操作则对考虑了特定于区域性的大小写、排序、格式化和语法分析规则的 String 的值执行。 区分区域性运算在显式声明的区域性或者隐式当前区域性的上下文中执行。 两种操作可以产生非常不同的结果(在相同的字符串上执行它们时)。
安全说明
如果应用程序进行有关符号标识符(如文件名或命名管道)或持久数据(如 XML 文件中基于文本的数据)的安全决策,则该操作应该使用序号比较而不是区分区域性的比较。 这是因为根据起作用的区域性的不同,区分区域性的比较可产生不同的结果,而序号比较则仅依赖于所比较字符的二进制值。
重要事项
执行字符串操作的大多数方法都包括带有 StringComparison 类型的参数的重载,这使您可以指定该方法执行序号或区分区域性的操作。 一般情况下,您应该调用此重载让您的方法的意图明确方法调用的目的。 在字符串上使用序号和区分区域性的操作的最佳做法和指南,请参见 在 .NET Framework 中使用字符串的最佳做法。
casing 、parsing and formatting、comparison and sorting 和 testing for equality 可以是序号操作或区分区域性的操作。 以下各节讨论了操作的每个类别。
大小写
大小写规则确定如何更改 Unicode 字符的大小写;例如,从小写变为大写。 通常,大小写操作在字符串比较之前执行。 例如,一个字符串可能会转换为大写,以便它可以与其他大写字符串作比较。 可通过调用 ToLower 或 ToLowerInvariant 方法将字符串中的字符转换为小写,还可以通过调用 ToUpper 或 ToUpperInvariant 方法将其转换为大写。 此外,您可以使用 TextInfo.ToTitleCase 方法将字符串转换为词首大写的形式。
大小写操作可以基于当前区域性、指定区域性或固定区域性的规则。 将字符串转换为大写时,下面的示例演示了不同的区域性之间不同的大小写规则。
C#
VB
复制
using System;
using System.Globalization;
using System.IO;
public class Example
{
public static void Main()
{
StreamWriter sw = new StreamWriter(@".\case.txt");
string[] words = { "file", "sıfır", "Dženana" };
CultureInfo[] cultures = { CultureInfo.InvariantCulture,
new CultureInfo("en-US"),
new CultureInfo("tr-TR") };
foreach (var word in words) {
sw.WriteLine("{0}:", word);
foreach (var culture in cultures) {
string name = String.IsNullOrEmpty(culture.Name) ?
"Invariant" : culture.Name;
string upperWord = word.ToUpper(culture);
sw.WriteLine(" {0,10}: {1,7} {2, 38}", name,
upperWord, ShowHexValue(upperWord));
}
sw.WriteLine();
}
sw.Close();
}
private static string ShowHexValue(string s)
{
string retval = null;
foreach (var ch in s) {
byte[] bytes = BitConverter.GetBytes(ch);
retval += String.Format("{0:X2} {1:X2} ", bytes[1], bytes[0]);
}
return retval;
}
}
// The example displays the following output:
// file:
// Invariant: FILE 00 46 00 49 00 4C 00 45
// en-US: FILE 00 46 00 49 00 4C 00 45
// tr-TR: FİLE 00 46 01 30 00 4C 00 45
//
// sıfır:
// Invariant: SıFıR 00 53 01 31 00 46 01 31 00 52
// en-US: SIFIR 00 53 00 49 00 46 00 49 00 52
// tr-TR: SIFIR 00 53 00 49 00 46 00 49 00 52
//
// Dženana:
// Invariant: DžENANA 01 C5 00 45 00 4E 00 41 00 4E 00 41
// en-US: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
// tr-TR: DŽENANA 01 C4 00 45 00 4E 00 41 00 4E 00 41
分析和格式设置
格式化和分析为反向操作。 格式化规则决定如何将值,例如日期和时间或者数字,转换为它的字符串表示形式,而语法分析规则则确定如何将字符串表示形式转换为值。 格式化和分析规则都取决于区域性约定。 解释区域性特定的数据字符串时,下面的示例演示可能引发的多义性。 若未知用于生成日期字符串的区域性约定,则不可能知道 03/01/2011、3/1/2011 及 01/03/2011 是表示 2011 年 1 月 3 日还是表示 2011 年 3 月 1 日。
C#
VB
复制
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
DateTime date = new DateTime(2011, 3, 1);
CultureInfo[] cultures = { CultureInfo.InvariantCulture,
new CultureInfo("en-US"),
new CultureInfo("fr-FR") };
foreach (var culture in cultures)
Console.WriteLine("{0,-12} {1}", String.IsNullOrEmpty(culture.Name) ?
"Invariant" : culture.Name,
date.ToString("d", culture));
}
}
// The example displays the following output:
// Invariant 03/01/2011
// en-US 3/1/2011
// fr-FR 01/03/2011
同样,如以下示例所示,单个字符串可以产生不同的日期,这取决于在分析操作中使用的区域性的约定。
C#
VB
复制
using System;
using System.Globalization;
public class Example
{
public static void Main()
{
string dateString = "07/10/2011";
CultureInfo[] cultures = { CultureInfo.InvariantCulture,
CultureInfo.CreateSpecificCulture("en-GB"),
CultureInfo.CreateSpecificCulture("en-US") };
Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}\n", "Date String", "Culture",
"Month", "Day");
foreach (var culture in cultures) {
DateTime date = DateTime.Parse(dateString, culture);
Console.WriteLine("{0,-12} {1,10} {2,8} {3,8}", dateString,
String.IsNullOrEmpty(culture.Name) ?
"Invariant" : culture.Name,
date.Month, date.Day);
}
}
}
// The example displays the following output:
// Date String Culture Month Day
//
// 07/10/2011 Invariant 7 10
// 07/10/2011 en-GB 10 7
// 07/10/2011 en-US 7 10
字符串比较和排序
排序规则确定 Unicode 字符的字母顺序,以及两个字符串如何互相比较。 例如 String.Compare(String, String, StringComparison) 根据 StringComparison 参数比较两个字符串。 如果参数值为 StringComparison.CurrentCulture,则方法执行使用当前区域性的约定的语义比较;如果参数值为 StringComparison.Ordinal,则方法执行序号比较。 因此,如以下示例所示,如果当前区域性是美国。 英语,对 String.Compare(String, String, StringComparison) 方法(使用区分区域性的比较)的第一次调用认为“a”小于“A”,但对相同的方法(使用序号比较)的第二次调用认为“a”大于“A”。
C#
VB
复制
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
Console.WriteLine(String.Compare("A", "a", StringComparison.CurrentCulture));
Console.WriteLine(String.Compare("A", "a", StringComparison.Ordinal));
}
}
// The example displays the following output:
// 1
// -32
.NET Framework 支持单词、字符串和序号排序规则。
单词排序会执行区分区域性的字符串比较,在这种比较中,某些非字母数字 Unicode 字符可能会具有特殊的权重。 例如,连字符(“-”)的权重非常小,因此“coop”和“co-op”在排序列表中是紧挨着出现的。 有关使用单词排序规则比较两个字符串的 String 方法列表,请参见 String Operations by Category 部分。
字符串排序同时执行区分区域性的比较。 它与单词排序相似,唯一区别是字符串排序中不存在特殊情况,所有非字母数字符号均排在所有字母数字 Unicode 字符之前。 可通过调用 CompareInfo.Compare 方法过载(其具有 options 参数,该参数为 CompareOptions.StringSort 的提供值)来使用字符串排序规则比较两个字符串。 请注意,这是 .NET Framework 提供的唯一一个使用字符串排序规则比较两个字符串的方法。
序号排序基于字符串中每个 Char 对象的数值对字符串进行比较。 序号比较自动区分大小写,因为字符的小写和大写版本有着不同的码位。 但是,如果大小写并不重要,则可以指定忽略大小写的序号比较。 这相当于使用固定区域性将字符串转换为大写,然后对结果执行序号比较。 有关比较实用序号排序规则的两个字符串的 String 方法列表,请参见 String Operations by Category 部分。
区分区域性的比较是显式或隐式使用 CultureInfo 对象的任何比较,包括由 CultureInfo.InvariantCulture 属性指定的固定区域性。 隐式区域性为当前区域性,它是由 Thread.CurrentCulture 和 CultureInfo.CurrentCulture 属性指定。 区分区域性的比较通常适用于排序,而序号比较则不适合。 序号比较通常适用于确定两个字符串是否相等(即,确定标识),而区分区域性的比较则不适用。
注意
区分区域性的排序和用于字符串比较的大小写规则取决于 .NET Framework 的版本。 在 .NET Framework 4 中,排序、大小写转换、规范化和 Unicode 字符信息是与 Windows 7 同步的,并符合Unicode 5.1 标准。
有关单词、字符串和序号排序规则的更多信息,请参见 System.Globalization.CompareOptions 主题。 有关何时使用每个规则的建议,请参阅 在 .NET Framework 中使用字符串的最佳做法。
通常,您不要直接调用字符串比较方法(比如 Compare)来确定字符串的排序顺序。 相反,比较方法都是通过排序方法调用的,比如 Array.Sort 或 List
C#
VB
复制
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
public class Example
{
public static void Main()
{
string[] strings = { "coop", "co-op", "cooperative",
"co\u00ADoperative", "cœur", "coeur" };
// Perform a word sort using the current (en-US) culture.
string[] current = new string[strings.Length];
strings.CopyTo(current, 0);
Array.Sort(current, StringComparer.CurrentCulture);
// Perform a word sort using the invariant culture.
string[] invariant = new string[strings.Length];
strings.CopyTo(invariant, 0);
Array.Sort(invariant, StringComparer.InvariantCulture);
// Perform an ordinal sort.
string[] ordinal = new string[strings.Length];
strings.CopyTo(ordinal, 0);
Array.Sort(ordinal, StringComparer.Ordinal);
// Perform a string sort using the current culture.
string[] stringSort = new string[strings.Length];
strings.CopyTo(stringSort, 0);
Array.Sort(stringSort, new SCompare());
// Display array values
Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}\n",
"Original", "Word Sort", "Invariant Word",
"Ordinal Sort", "String Sort");
for (int ctr = 0; ctr < strings.Length; ctr++)
Console.WriteLine("{0,13} {1,13} {2,15} {3,13} {4,13}",
strings[ctr], current[ctr], invariant[ctr],
ordinal[ctr], stringSort[ctr] );
}
}
// IComparer
internal class SCompare : IComparer
{
public int Compare(string x, string y)
{
return CultureInfo.CurrentCulture.CompareInfo.Compare(x, y, CompareOptions.StringSort);
}
}
// The example displays the following output:
// Original Word Sort Invariant Word Ordinal Sort String Sort
//
// coop cœur cœur co-op co-op
// co-op coeur coeur coeur cœur
// cooperative coop coop coop coeur
// cooperative co-op co-op cooperative coop
// cœur cooperative cooperative cooperative cooperative
// coeur cooperative cooperative cœur cooperative
警告
如果您比较字符串的主要目的是确定它们是否相等,则应调用 String.Equals 方法。 通常,您应该使用 Equals 执行初始比较。 该 String.Compare 方法主要用于排序字符串。
字符串搜索方法,比如 String.StartsWith 和 String.IndexOf,也可以执行区分区域性的或序号字符串比较。 下面的示例使用 IndexOf 方法演示了序号和区分区域性比较之间的差异。 区分区域性的搜索,其中当前文化为英语(美国),认为子字符串“oe”要匹配连字“œ”。 由于软连字符 (U+00AD)是一个零宽度字符,搜索将该软连字符视为与 Empty 等同且在字符串开头找到匹配。 另一方面,序号的搜索没有在两种情况中找到匹配。
C#
VB
复制
using System;
public class Example
{
public static void Main()
{
// Search for "oe" and "œu" in "œufs" and "oeufs".
string s1 = "œufs";
string s2 = "oeufs";
FindInString(s1, "oe", StringComparison.CurrentCulture);
FindInString(s1, "oe", StringComparison.Ordinal);
FindInString(s2, "œu", StringComparison.CurrentCulture);
FindInString(s2, "œu", StringComparison.Ordinal);
Console.WriteLine();
string s3 = "co\u00ADoperative";
FindInString(s3, "\u00AD", StringComparison.CurrentCulture);
FindInString(s3, "\u00AD", StringComparison.Ordinal);
}
private static void FindInString(string s, string substring, StringComparison options)
{
int result = s.IndexOf(substring, options);
if (result != -1)
Console.WriteLine("'{0}' found in {1} at position {2}",
substring, s, result);
else
Console.WriteLine("'{0}' not found in {1}",
substring, s);
}
}
// The example displays the following output:
// 'oe' found in œufs at position 0
// 'oe' not found in œufs
// 'œu' found in oeufs at position 0
// 'œu' not found in oeufs
//
// '' found in cooperative at position 0
// '' found in cooperative at position 2
相等性测试
使用 String.Compare 方法来确定按排序顺序时两个字符串的关系。 通常,这是区分区域性的操作。 相比之下,调用 String.Equals 方法测试相等性。 因为平等测试通常比较用户输入和一些已知字符串,例如,有效用户名、 密码或文件系统路径,它通常是序号操作。
警告
通过调用 String.Compare 方法来进行平等性测试并确定返回值是否为零是可能的。 但是,不推荐这种做法。 要确定两个字符串是否相等,应该调用 String.Equals 方法的其中一个过载。 要调用的优选过载为实例 Equals 方法或静态 Equals 方法,因为两种方法都包含明确指定比较类型的 System.StringComparison 参数。
当改用一个序号时,下面的示例演示了执行相等区分区域性的比较的危险。 在这种情况下,代码的目的是通过使用字符串“FILE://”对 URL 的开头进行不区分大小写的比较来禁止由“FILE://”或“file://”开始的 URL 访问文件系统。 然而,如果使用“file://”开头的 URL 上的土耳其 (土耳其) 区域性执行区分区域性的比较,则该相等比较失败,这是因为等同于土耳其小写“i”的大写是“İ”,而不是“I”。 其结果是,无意中允许文件系统访问。 另一方面,如果执行序号比较,那么相等性比较会成功,文件系统访问会被拒绝。
C#
VB
复制
using System;
using System.Globalization;
using System.Threading;
public class Example
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("tr-TR");
string filePath = "file://c:/notes.txt";
Console.WriteLine("Culture-sensitive test for equality:");
if (! TestForEquality(filePath, StringComparison.CurrentCultureIgnoreCase))
Console.WriteLine("Access to {0} is allowed.", filePath);
else
Console.WriteLine("Access to {0} is not allowed.", filePath);
Console.WriteLine("\nOrdinal test for equality:");
if (! TestForEquality(filePath, StringComparison.OrdinalIgnoreCase))
Console.WriteLine("Access to {0} is allowed.", filePath);
else
Console.WriteLine("Access to {0} is not allowed.", filePath);
}
private static bool TestForEquality(string str, StringComparison cmp)
{
int position = str.IndexOf("://");
if (position < 0) return false;
string substring = str.Substring(0, position);
return substring.Equals("FILE", cmp);
}
}
// The example displays the following output:
// Culture-sensitive test for equality:
// Access to file://c:/notes.txt is allowed.
//
// Ordinal test for equality:
// Access to file://c:/notes.txt is not allowed.
返回备注
正常化
某些 Unicode 字符具有多个表示形式。 例如,以下任意码位可以表示字母“ắ”:
U+1EAF
U+0103 U+0301
U+0061 U+0306 U+0301
如果一个字符存在多种表示形式,会使搜索、排序、匹配和其他字符串操作变得复杂。
Unicode 标准定义了一个称作正常化的过程。对于字符的任何二进制等效表示形式,该过程都可以返回一个 Unicode 字符的二进制表示形式。 正常化可以使用几种算法,这些算法称作正常化形式,它们遵守不同的规则。 目前,.NET Framework 支持 Unicode 正常化形式 C、D、KC 和 KD。 如果字符串被正常化为同一范式,则可以使用序号比较对它们进行比较。 有关正则化和正则化窗体的更多信息,请参见 System.Text.NormalizationForm。
可通过调用 String.IsNormalized() 方法确定是否将字符串正常化为范式 C,也可以调用 String.IsNormalized(NormalizationForm) 方法来确定是否将字符串正常化为指定范式。 还可以调用 String.Normalize() 方法将字符串转换为范式 C,或调用 String.Normalize(NormalizationForm) 方法将字符串转换为指定的范式。
下面的示例阐释了字符串正常化。 它在三个不同的字符串中用三种不同的方式定义了字母“ố”,并使用相等性序号比较来确定每个字符串与其他两个字符串是不同的。 然后它将每个字符串转换为支持的范式,并再次执行指定范式中的每个字符串的序号比较。 在每种情况下,第二次相等测试表明字符串是相等的。
C#
VB
复制
using System;
using System.Globalization;
using System.IO;
using System.Text;
public class Example
{
private static StreamWriter sw;
public static void Main()
{
sw = new StreamWriter(@".\TestNorm1.txt");
// Define three versions of the same word.
string s1 = "sống"; // create word with U+1ED1
string s2 = "s\u00F4\u0301ng";
string s3 = "so\u0302\u0301ng";
TestForEquality(s1, s2, s3);
sw.WriteLine();
// Normalize and compare strings using each normalization form.
foreach (string formName in Enum.GetNames(typeof(NormalizationForm)))
{
sw.WriteLine("Normalization {0}:\n", formName);
NormalizationForm nf = (NormalizationForm) Enum.Parse(typeof(NormalizationForm), formName);
string[] sn = NormalizeStrings(nf, s1, s2, s3);
TestForEquality(sn);
sw.WriteLine("\n");
}
sw.Close();
}
private static void TestForEquality(params string[] words)
{
for (int ctr = 0; ctr <= words.Length - 2; ctr++)
for (int ctr2 = ctr + 1; ctr2 <= words.Length - 1; ctr2++)
sw.WriteLine("{0} ({1}) = {2} ({3}): {4}",
words[ctr], ShowBytes(words[ctr]),
words[ctr2], ShowBytes(words[ctr2]),
words[ctr].Equals(words[ctr2], StringComparison.Ordinal));
}
private static string ShowBytes(string str)
{
string result = null;
foreach (var ch in str)
result += String.Format("{0} ", Convert.ToUInt16(ch).ToString("X4"));
return result.Trim();
}
private static string[] NormalizeStrings(NormalizationForm nf, params string[] words)
{
for (int ctr = 0; ctr < words.Length; ctr++)
if (! words[ctr].IsNormalized(nf))
words[ctr] = words[ctr].Normalize(nf);
return words;
}
}
// The example displays the following output:
// sống (0073 1ED1 006E 0067) = sống (0073 00F4 0301 006E 0067): False
// sống (0073 1ED1 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
// sống (0073 00F4 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): False
//
// Normalization FormC:
//
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
// Normalization FormD:
//
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
//
//
// Normalization FormKC:
//
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
// sống (0073 1ED1 006E 0067) = sống (0073 1ED1 006E 0067): True
//
//
// Normalization FormKD:
//
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
// sống (0073 006F 0302 0301 006E 0067) = sống (0073 006F 0302 0301 006E 0067): True
返回备注
按类别划分的字符串操作
String 类提供成员用于比较字符串,测试字符串是否相等,查找字符串中的字符或子字符串,修改字符串,提取字符串的子字符串,组合字符串,格式化值,复制字符串和使字符串规范化。
比较字符串
通过使用以下 String 方法比较字符串,以确定其在排序顺序中的相对位置:
Compare 返回一个指示排序顺序中某个字符串与另一个字符串之间的关系的整数。
CompareOrdinal 返回一个指示某个字符串与另一个字符串之间的关系(基于它们的码位的比较)的整数。
CompareTo 返回一个指示排序顺序中当前字符串实例与第二个字符串之间的关系的整数。 该 CompareTo 方法向 String 类提供 IComparable 和 IComparable
字符串相等性测试
请调用 Equals 方法以确定两个字符串是否相等。 实例 Equals 和静态 Equals 重载允许您指定比较是区分区域性还是序号;事例是考虑还是忽略。 大多数相等性测试都是序号的,并且确定系统资源(例如文件系统对象)的访问权限的相等性比较应始终为序号的。
查找字符串中的字符
String 类包含两种搜索方法:
返回 Boolean 值以指示特定的子字符串是否存在于某个字符串实例中的方法。 这些控件包括 Contains、EndsWith 和 StartsWith 方法。
指示字符串实例中某个子字符串的起始位置的方法。 这些包括 IndexOf、IndexOfAny、LastIndexOf 和 LastIndexOfAny 方法。
修改 字符串
String 类包括以下方法,可用于修改字符串的值:
Insert 将一个字符串插入到当前的 String 实例中。
PadLeft 将指定字符的一个或多个匹配项插入到字符串的开始位置。
PadRight 将指定字符的一个或多个匹配项插入到字符串的开始位置。
Remove 从当前的 String 实例中删除一个子字符串。
Replace 在当前的 String 实例中将一个子字符串替换成另一个子字符串。
ToLower 和 ToLowerInvariant 将字符串中的所有字符转换为小写。
ToUpper 和 ToUpperInvariant 将字符串中的所有字符转换为大写。
Trim 从字符串的开始位置和末尾移除所有空白字符。
TrimEnd 从字符串的末尾移除所有空白字符。
TrimStart 从字符串的开始位置移除所有空白字符。
重要事项
所有字符串修改方法都返回新的 String 对象。 它们不修改当前实例的值。
从字符串中提取子字符串
该 String.Split 方法将单独字符串分隔成多个字符串。 该方法的重载可以让您指定多个分隔符,以确定该方法提取的子字符串的最大数量,并确定空字符串(当分隔符相邻时发生)是否包括在返回的字符串中。
组合字符串
以下 String 方法可以用于字符串串联:
Concat 将一个或多个子字符串合并为一个字符串。
Join 将一个或多个子字符串连接成一个元素,并在每个字符串之间添加分隔符。
格式化值
String.Format 方法使用复合格式化功能用某些对象或值的字符串表示来替代字符串中一个或多个占位符。 Format 通常用于执行以下操作:
在字符串中嵌入数字值的字符串表示形式。
在字符串中嵌入日期和时间值的字符串表示形式。
将枚举值的字符串表示形式嵌入字符串中。
要在字符串中嵌入支持 IFormattable 接口的某些对象的字符串表示形式。
在较大字符串中向右或向左对齐字段中的子字符串。
复制字符串
可以通过调用以下 String 方法对字符串进行复制:
Clone 返回现有 String 对象的引用。
Copy 创建现有字符串的副本。
CopyTo 将字符串的一部分复制到一个字符数组中。
将字符串正常化
在 Unicode 中,单个字符可以有多个码位。 规范化将这些等效字符转换为相同的二进制表示形式。 该 String.Normalize 方法执行规范化并且 String.IsNormalized 方法确定一个字符串是否规范化。
返回备注
System.String 类例子
线程安全
此类型是线程安全的。
版本信息
.NET Framework 受以下版本支持:4、3.5、3.0、2.0、1.1、1.0 .NET Framework Client Profile 受以下版本支持:4、3.5 SP1 受以下版本支持:
适用平台
Windows 7, Windows Vista SP1 或更高版本, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008(不支持服务器核心), Windows Server 2008 R2(支持 SP1 或更高版本的服务器核心), Windows Server 2003 SP2 .NET Framework 并不是对每个平台的所有版本都提供支持。有关支持的版本的列表,请参见.NET Framework 系统要求。