字符串字面值
原始字符串
和很多语言相似,C#使用""
来包括字符串字面值。字符串字面值可以是普通的字符串,也可以包含以\
开头的转义字符。如果想让字符串字面值中包含\
就必须写成\\
这样的。但是,像Windows系统文件路径这样的字符串,这就是很不方便的。例如C:\Windows\System
这样的路径就必须写成"C:\\Windows\\System
这样的形势。这时候可以使用@
放在双引号的前面,表示原始字符串。原始字符串中的所有以\
开头的都会按照字符串字面解释,不会被解释成转义序列。这样一来,刚才那个路径就可以写成这样的形式,@"C:\Windows\System
。原始字符串还可以跨越多行。
内插字符串
如果在双引号之前添加$
的话,字符串就变成了内插字符串,这在要把几个字符串变量和字符串常量拼接在一起的时候非常有用。
string s1 = "abc";
string s2 = "567";
//使用普通方法
Console.WriteLine("{0} {1}", s1, s2);
//使用内插字符串
Console.WriteLine($"{s1} {s2}");
//内插字符串中还可以调用方法
Console.WriteLine($"{s1.ToUpper()} {s2}");
可以看到,如果要将很多歌字符串变量和字符串字面值拼接在一起,使用内插字符串是很方便的。
字符串
在C#中,字符串使用关键字string定义,该关键字其实是System.String类的缩写。string类有大量的方法,可以完成各种各样的事情。详情可参考MSDN。以下是一些基本操作。
//创建字符串
string str1 = "I like apples,";
Console.WriteLine(str1);
//追加字符串
str1 += "but you love pears.";
Console.WriteLine(str1);
//替换字符串
str1 = str1.Replace("pears", "bananas");
Console.WriteLine(str1);
//转换为大写
Console.WriteLine(str1.ToUpper());
还可以完成一些更实际的操作。例如,下面是判断字符串是否是有效的电子邮件地址的代码。
static void StringTest()
{
string rightEmail = "test@hotmail.com";
string wrongEmail = "notaemail";
Console.WriteLine($"{rightEmail}是否是正确的电子邮件地址:{IsEmail(rightEmail)}");
Console.WriteLine($"{wrongEmail}是否是正确的电子邮件地址:{IsEmail(wrongEmail)}");
}
//判断电子邮件地址的函数
private static bool IsEmail(string email)
{
int index = email.IndexOf('@');
if (index < 0)
{
return false;
}
string username = email.Substring(0, index);
if (string.IsNullOrWhiteSpace(username))
{
return false;
}
string domain = email.Substring(index);
if (domain.Contains('.'))
{
return true;
}
else
{
return false;
}
}
但是需要注意的是,string是不可变对象。任何修改string内容的操作,其实都会创建一个新的字符串。这在一般情况下没有问题,如果要进行大量的字符串处理,就会产生性能问题。这时候可以考虑使用StringBuilder类。
StringBuilder类
StringBuilder类是一个专门用于创建动态字符串的类。在字符串插入、追加、修改、删除等方面的效率很高,因为它是一个可变的字符串,所有的操作都会应用到字符串上,而不是创建一个新的字符串。因此在操作大量字符串的时候,应该使用它。和ArrayList一样,当内部的容量不足的时候,才会重新分配更大的存储空间。所以可以预先指定一个比较大的值来提高该类的性能。该类的详细方法可以参考MSDN。
//创建StringBuilder
StringBuilder sb = new StringBuilder("I like apples,");
Console.WriteLine(sb.ToString());
//追加
sb.Append("but you love pears.");
Console.WriteLine(sb.ToString());
//替换
sb.Replace("pears", "bananas");
Console.WriteLine(sb.ToString());
正则表达式
正则表达式是一种专门用来处理字符串的技术,可以用简单的操作来完成很多复杂的功能,例如判断一个字符串是否是一个合法的电子邮件地址,找出所有以M开头并且长度大于4的单词等等。这样的操作都可以用String和StringBuilder类实现,但是正则表达式的方式非常简洁。用电子邮件的例子就可以说明。
MyConsole.PrintNextSection("正则表达式验证电子邮件示例");
string rightEmail = "test@hotmail.com";
string wrongEmail = "@notaemail";
const string pattern = @"\w+@\w+\.\w+";
Regex regex = new Regex(pattern);
Console.WriteLine($"{rightEmail}是否是电子邮件地址:{regex.IsMatch(rightEmail)}");
Console.WriteLine($"{wrongEmail}是否是电子邮件地址:{regex.IsMatch(wrongEmail)}");
字符类
这里只列举最常见的一些字符类。
字符 | 说明 | 例子 |
---|---|---|
\w | 匹配单个单词字符 | ‘a’、’c’、’1’ |
\W | 匹配任意非单词字符 | ‘.’、’,’、’*’ |
\d | 匹配任意十进制数字字符 | ‘1’、’2’、’0’ |
\D | 匹配任意非数字字符 | ‘a’、’,’ |
\s | 任意空白字符 | ’ ‘、’\t’ |
\S | 任意非空白字符 | ‘a’、’1’ |
[abc] | a或者b或者c | ‘a’、’b’、’c’ |
[^abc] | 不是a、b或者c的单个字符 | ‘d’、’e’、’f’ |
[0-9] | 0到9任意数字 | ‘1’、’2’ |
[a-zA-Z] | 所有字母中的一个 | ‘a’、’B’ |
. | 通配符,匹配任意一个字符 | ‘a’、’1’ |
量词
量词作用在某一个字符类前面,指定它出现的次数。量词还有很多,这里不一一列举了,详细情况请参阅MSDN。
符号 | 说明 |
---|---|
? | 出现0次或1次 |
* | 出现0次或多次 |
+ | 出现1次或多次 |
{n} | 正好出现n次 |
{n,m} | 出现次数不小于n,不大于m |
{n,} | 出现次数不小于n次 |
定位点
字符 | 说明 |
---|---|
^ | 字符串或一行的开始 |
$ | 字符串或一行的结束 |
\G | 上一个匹配的结束 |
\b | \b和\B的边界处 |
\A | 字符串的开始 |
\Z | 字符串的结束 |
知道了这些,就可以知道上面验证电子邮件地址的正则表达式\w+@\w+\.\w+
的含义了。
最后,再看一个将长度大于3的单词首字母大写的例子。
string titleString = "This is a beginning of the new world";
string pattern = @"\w{3,}";
//替换函数,第三个参数是一个委托,
//表示将每一个匹配的字符串转化成首字母大写的形式
titleString = Regex.Replace(titleString, pattern, match => Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(match.Value));
Console.WriteLine(titleString);