5.3 字符串的处理
到目前为止,对字符串的使用还仅限于把字符串写到控制台,从控制台读取字符串,以及使用+运算符连接字符串。在编写较有趣的应用程序时,会发现字符串的操作非常多。所以,下面占用几页的篇幅介绍C#中较常用的字符串处理技巧。
首先要注意,string类型的变量可以看成char变量的只读数组。这样,就可以使用下面的语法访问每个字符:
string myString = "A string"; char myChar = myString[1];
但不能采用这种方式为各个字符赋值。为获得一个可写的char数组,可以使用下面的代码,其中使用了数组变量的ToCharArray()命令:
string myString = "A string"; char[] myChars = myString.ToCharArray();
接着就可以采用标准方式处理char数组了。也可在foreach循环中使用字符串,例如:
foreach (char character in myString) { WriteLine($"{character}"); }
与数组一样,还可以使用myString.Length获取元素个数,这将给出字符串中的字符数,例如:
string myString = ReadLine(); WriteLine($"You typed {myString.Length} characters.");
其他基本字符串处理技巧采用与这个<string>.ToCharArray()命令类似的格式使用命令。两个简单却有效的命令是<string>.ToLower()和<string>.ToUpper()。它们可以分别把字符串转换为小写或大写形式。为理解它们的重要作用,可以考虑下面的情形:要检查用户的某个响应,例如字符串yes。如果可以把用户输入的字符串转换为小写形式,就也能检查字符串YES、Yes、yeS等,第4章介绍了这样一个示例:
string userResponse = ReadLine(); if (userResponse.ToLower() == "yes") { // Act on response. }
注意,这个命令与本节的其他命令一样,并未真正改变应用它的字符串。把这个命令与字符串结合使用,就会创建一个新的字符串,以便与另一个字符串进行比较(如上所述),或者赋给另一个变量。该变量可以是当前操作的变量,例如:
userResponse = userResponse.ToLower();
记住这一点很重要,因为只写出下面的代码是没用的:
userResponse.ToLower();
下面看看在简化用户输入方面还可以做什么。如果用户无意间在输入内容的前面或后面添加了多余的空格,会怎样?此时,上述代码就不起作用了。这就需要删除输入字符串前后的空格,此时可以使用<string>.Trim()命令来处理:
string userResponse = ReadLine(); userResponse = userResponse.Trim(); if (userResponse.ToLower() == "yes") { // Act on response. }
使用该命令,还可以检测如下字符串:
" YES" "Yes "
也可以使用这些命令删除其他字符,只要在一个char数组中指定这些字符即可,例如:
char[] trimChars = {' ', 'e', 's'}; string userResponse = ReadLine(); userResponse = userResponse.ToLower(); userResponse = userResponse.Trim(trimChars); if (userResponse == "y") { // Act on response. }
这将删除字符串前后的所有空格、字母e和s。如果字符串中没有其他字符,就会检测以下字符串:
"Yeeeees" " y"
还可以使用<string>.TrimStart()和<string>.TrimEnd()命令,它们可以把字符串前面或后面的空格删掉。使用这些命令时也可以指定char数组。
还有另外两个字符串命令可以处理字符串的空格:<string>.PadLeft()和<string>.PadRight()。它们可以在字符串的左边或右边添加空格,使字符串达到指定的长度。其语法如下:
<string>.PadX(<desiredLength>);
例如:
myString = "Aligned"; myString = myString.PadLeft(10);
这将在myString中把3个空格添加到单词Aligned的左边。这些方法可以用于在列中对齐字符串,特别适于放置包含数字的字符串。
与修整命令一样,还可以按第二种方式使用这些命令,即提供要添加到字符串上的字符。但是这需要一个char字符,而不是像修整命令那样指定一个char数组。例如:
myString = "Aligned"; myString = myString.PadLeft(10, '-');
这将在myString的开头加上3个短横线。
还有许多这样的字符串处理命令,其中一些只用于非常特殊的情况,在后面的章节中遇到它们时再进行讨论。在继续下面的内容之前,有必要介绍Visual Studio 2015中的一个特性,前几章曾提及(特别是本章)这个特性。下面的示例会试验语句自动完成功能,IDE通过这种功能给出用户有可能要插入的代码。
试一试:VS中的语句自动完成功能:Ch05Ex05\Program.cs
(1)在C:\BegVCSharp\Chapter05目录中创建一个新的控制台应用程序Ch05Ex05。
(2)在Program.cs中输入下列代码,注意输入过程中弹出的窗口:
static void Main(string[] args) { string myString = "This is a test."; char[] separator = {' '}; string[] myWords; myWords = myString. }
(3)输入最后的句点时,注意会弹出如图5-11所示的窗口。
图5-11
(4)不要移动光标,键入sp,弹出窗口就会改变,显示一个工具提示窗口,如图5-12所示。
图5-12
(5)输入字符“(se”,会弹出另一个窗口和工具提示,如图5-13所示。
图5-13
(6)输入两个字符“); ”,代码如下所示,弹出窗口随之消失:
static void Main(string[] args)
{
string myString = "This is a test.";
char[] separator = {' '};
string[] myWords;
myWords = myString.Split(separator);
}
(7)添加下述代码,注意弹出的窗口:
static void Main(string[] args)
{
string myString = "This is a test.";
char[] separator = {' '};
string[] myWords;
myWords = myString.Split(separator);
foreach (string word in myWords)
{
WriteLine($"{word}");
}
ReadKey();
}
(8)执行代码,结果如图5-14所示。
图5-14
示例说明
在这段代码中,要注意两点。第一点是所使用的新字符串命令,第二点是使用了自动完成功能。使用命令<string>.Split()把string字符串转换为string数组,把它在指定的位置隔开。这些位置采用char数组形式,在本例中该数组只有一个元素,即空格字符:
char[] separator = {' '};
下面的代码把字符串在每个空格处分解开,并获取得到的子字符串,即得到包含单独单词的数组:
string[] myWords; myWords = myString.Split(separator);
接着使用foreach循环迭代这个数组中的单词,并把这些单词写到控制台:
foreach (string word in myWords) { WriteLine($"{word}"); }
注意:得到的每个单词都没有空格,单词的内部和两端都没有空格。在使用split()时,删除了分隔符。