String用来表示文本,即一系列 Unicode 字符。字符串是我们开发过程中频繁使用的对象,我们在软件界面上提示用户的所有一切都是字符串:不管是发票的日期还是发票的编号,或者是发票的金额虽然在定义数据类型时候分别应该是DateTime、double或string,但当界面呈现的时候,都是以文本的形式呈现,也就是string格式。
字符串的声明非常的简单,使用””(双引号)描述内容。
static void Main(string[] args)
{
string s = "Hello";
}
字符串是 Unicode 字符的有序集合,用于表示文本。所以String 对象是 System.Char 对象的有序集合,用于表示字符串。String 对象的值是该有序集合的内容,并且该值是不可变的。字符串本质是字符数组——这是一个非常重要的概念,了解这个概念就可以全面的理解和把握字符串的各种特征。
static void Main(string[] args)
{
char[] cStr = new char[] { 'H', 'e', 'l', 'l', 'o' };
string s = new string(new char[] { 'H', 'e', 'l', 'l', 'o' });
}
字符串本质是字符数组是一个非常重要的概念,了解这个概念就可以全面的理解和把握字符串的各种特征。
由于字符串是字符数组,因此字符串可以直接当数组使用,通过下标的模式访问字符串中的每一个字符,或者可以将字符串转为字符数组。以下代码描述了这个概念:
static void Main(string[] args)
{
string s = "Hello";
for (int i = 0; i <= s.Length - 1; i++) //将字符串当数组
{
System.Console.WriteLine("第{0}个字符是:{1}", i, s[i]);
}
char[] cStr = s.ToCharArray(); //将字符串转为字符数组
for (int i = 0; i <= cStr.Length - 1; i++)
{
System.Console.WriteLine(cStr[i]);
}
}
运行的结果如图3.1.7。
图3.1.7 字符串中的每个元素值
既然数组有IndexOf的方法返回指定元素在数组中的位置,string是char的数组,那也自然有这个方法。
static void Main(string[] args)
{
string s = "Hello";
System.Console.WriteLine(s.IndexOf('l')); //返回2
System.Console.WriteLine(s.LastIndexOf('l')); //返回3
System.Console.WriteLine(s.IndexOf('L')); //返回-1
}
运行的结果如图3.1.8。
图3.1.8 对字符串使用IndexOf结果
需要注意的是:IndexOf中的参数是’l’,单引号描述的是字符,双引号描述的是字符串。字符描述的是单个的字符,字符串描述的是一组字符文本。IndexOf和LastIndexOf配合可以让我们了解给定的字符在字符串中是否唯一。假设我们需要判断给定的字符串是否是一个合法的财务数字,合法的财务数字中小数点只能有一个,或者没有小数点,如下代码可以实现:
static void Main(string[] args)
{
string s = "12.24";
if (s.IndexOf('.') == s.LastIndexOf('.'))
{
System.Console.WriteLine("{0}小数点格式正确", s);
}
else
{
System.Console.WriteLine("{0}小数点格式不正确", s);
}
}
上述代码运行的结果能正确的检查小数点的格式情况,结果如图3.1.9所示:
图3.1.9小数点格式验证结果
如果要判断精度,则可以将字符串的长度和小数点的位置下标进行比较:
static void Main(string[] args)
{
string s = "12.24";
System.Console.WriteLine("小数的精度是{0}", s.Length - s.IndexOf('.') - 1);
}
结果为如图3.1.10。
图3.1.10精度判断结果
如果我们要获取字符串中一部分的值,可以使用Substring方法,该方法描述从指定的字符串位置开始返回指定个数的字符串。
static void Main(string[] args)
{
string s = "12.24";
System.Console.WriteLine("整数部分是{0}", s.Substring(0, s.IndexOf('.')));//从第一个字符取到小数点的位置之前的字符
System.Console.WriteLine("小数部分是{0}", s.Substring(s.IndexOf('.') + 1, s.Length - s.IndexOf('.') - 1));//从小数点的位置之后,到字符串的最后
System.Console.WriteLine("小数部分是{0}", s.Substring(s.IndexOf('.') + 1));//从小数点的位置之后,到字符串的最后
}
运行的结果如图3.1.11。
图3.1.11 使用Substring的结果
如果要把字符串中的英文字母全部改为大写或小写字母,string提供了两个方法:
static void Main(string[] args)
{
string s = "Hello";
System.Console.WriteLine(s.ToLower());
System.Console.WriteLine(s.ToUpper());
System.Console.WriteLine(s);
}
请注意运行的结果,如图3.1.12所示:
图3.1.12 使用ToLower & ToUpper的结果
上面代码的结果告诉了我们一个事实,字符串的内容是不会改变的,也就是说ToLower和ToUpper方法仅仅是返回一个新的字符串。这个特征在字符串的其他方法也同样有效,如果你要正真的改变字符串的值,必须要为字符串重新赋值。
static void Main(string[] args)
{
string s = "Hello";
s = s.ToUpper();
System.Console.WriteLine(s);
}
string还提供了一组用于修改字符串内容的方法,当然原先字符串的内容不改变,仅仅是返回新的字符串。
static void Main(string[] args)
{
string s = "Hello";
System.Console.WriteLine(s.Insert(2, "ABC")); //插入:HeABCllo
System.Console.WriteLine(s.Remove(2, 2)); //移除:Heo
System.Console.WriteLine(s.PadLeft(10, 'a')); //向左填充:aaaaaHello
System.Console.WriteLine(s.PadRight(10, 'a')); //向右填充:Helloaaaaa
System.Console.WriteLine(s.Replace("ll0", "110")); //替换:He11o
}
请仔细观察下图3.1.13运行的结果,字符串在多次的改变后其本身的值没有任何变化。
图3.1.13 字符串恒定性的体现
String还提供了一个很有意思的方法:Split。该方法允许我们对字符串通过给定的字符进行拆分,并返回一个字符串数组(是字符串数组而不是字符数组)。该数组包含了拆分后的一组字符串,就像我们小时候说的一刀两断,两刀三段。
下述代码描述了将IP地址拆分,并返回IP的每一段:
static void Main(string[] args)
{
string ipAddress = "192.168.1.100";
string[] ips = ipAddress.Split('.');
for (int i = 0; i <= ips.Length - 1; i++)
{
System.Console.WriteLine(ips[i]);
}
}
运行的结果如图3.1.14。
图3.1.14 显示IP地址每一段值
string中的每一个元素都是char,char提供了一系列的Is方法,该组方法能帮我们判断该字符是什么类型的字符:数字、字母、大小写字母、控制符、标点。以下代码描述了这个使用方式:
string s = "C# 锐利体验向我们描述了使用 Microsoft Visual Studio 2008 进行软件开发的工作";
int number = 0;
int letter = 0;
int punctuation = 0;
foreach (char c in s)
{
if (char.IsNumber(c))
{
number++;
}
if (char.IsLetter(c))
{
letter++;
}
if (char.IsPunctuation(c))
{
punctuation++;
}
}
System.Console.WriteLine("number:{0},letter:{1},punctuation:{2}", number, letter, punctuation);
图3.1.15 查字符个数的运行结果
字符串是非常常用的类,以下是对string类的功能摘要
String 类提供的成员执行以下操作:比较 String 对象;返回 String 对象内字符或字符串的索引;复制 String 对象的值;分隔字符串或组合字符串;修改字符串的值;将数字、日期和时间或枚举值的格式设置为字符串;对字符串进行规范化。
使用 Compare、CompareOrdinal、CompareTo、Equals、EndsWith 和 StartsWith 方法进行比较。
使用 IndexOf、IndexOfAny、LastIndexOf 和 LastIndexOfAny 方法可获取字符串中子字符串或 Unicode 字符的索引。
使用 Copy 和 CopyTo 可将字符串或子字符串复制到另一个字符串或 Char 类型的数组。
使用 Substring 和 Split 方法可通过原始字符串的组成部分创建一个或多个新字符串;使用 Concat 和 Join 方法可通过一个或多个子字符串创建新字符串。
使用 Insert、Replace、Remove、PadLeft、PadRight、Trim、TrimEnd 和 TrimStart 可修改字符串的全部或部分。
使用 ToLower、ToLowerInvariant、ToUpper 和 ToUpperInvariant 方法可更改字符串中 Unicode 字符的大小写。
使用 Format,可将字符串中的一个或多个格式项占位符替换为一个或多个数字、日期和时间或枚举值的文本表示形式。
使用 Length 属性可获取字符串中 Char 对象的数量;使用 Chars 属性可访问字符串中实际的 Char 对象。
使用 IsNormalized 方法可测试某个字符串是否已规范化为特定的范式。使用 Normalize 方法可创建规范化为特定范式的字符串。
初学者注意
要值得注意的是在 .NET Framework 中,String 对象可以包含嵌入的 null 值,这些值将算作字符串长度的一部分。但是,在某些语言(例如 C 和 C++)中,null 字符指示字符串的结尾,将不被视为字符串的一部分,并且将不算作字符串长度的一部分。字符串虽然是引用类型,但出于效率考虑,字符串以值类型的面貌出现。