C#基础--字符串和正则表达式
在占位符 中,格式字符串跟在表达式的后面,用冒号隔开。StringBuilder类则不同,每次操作都是对自身对象进行操作,而不是生成新的对象,其所占空间会随着内容的增加而扩充,这样,在做大量的修改操作时,不会因生成大量匿名对象而影响系统性能。StringTormat方法的第一个参数接受一个格式字符串,其中的占位符从0开始编号,其后是放入字符串空白处的参数。重复修改给定的字符串,效率会很低,它实际上
String
System.String类专门用于存储字符串,允许对字符串进行许多操作。此外,由于这种数据类型非常重要,C# 提供了它自己的关键字和相关的语法,以便使用这个类来轻松地处理字符串。使用运算符重载可以连接字符串:
string messagel = ’’Hello"; // returns "Hello"
messagel += ”,There"; // returns "Hello, There"
string message2 = messagel + "!"; // returns "Hello, There! "
c#还允许使用类似于索引器的语法来提取指定的字符:
string message = ’’Hello”;
char char4 = message[4]; // returns "0"
这个类可以完成许多常见的任务,如替换字符、删除空白和把字母变成大写形式等。
string 和 stringbuilder
String类是一个功能非常强大的类,它实现许多很有用的方法。但是,String类存在一个问题:
重复修改给定的字符串,效率会很低,它实际上是一个不可变的数据类型,这意味着一旦对字符串对象进行了 初始化,该字符串对象就不能改变了。
string greetingText = "Hello from all the people at Wrox Press.
greetingText += **We do hope you enjoy this book as much as we enjoyed writing it.";
在执行这段代码时,首先创建一个System.String类型的对象,并把它初始化为文本“Hello from all lhepeople at Wrox Press. ”,注意句号后面有一个空格。此时.NET运行库会为该字符串分配足够的内存来保存这个文本(41 个字符),再设置变量greetingText来表示这个字符串实例。
从语法上看,下一行代码是把更多的文本添加到字符串中。实际上并非如此,在此是创建一个新字符串实 例,给它分配足够的内存,以存储合并的文本(共104个字符)。把最初的文本“Hello from all the people at Wrox Press. ” 复制到这个新字符串中,再加上额外的文本 “We do hope you enjoy this book as much as we enjoyed writing it.”。然后更新存储在变量greetingText中的地址,使变量正确地指向新的字符串对象。现在没有引用旧的字符串 对象一不再有变量引用它,下一次垃圾收集器清理应用程序中所有未使用的对象时,就会删除它。
StringBuilder类则不同,每次操作都是对自身对象进行操作,而不是生成新的对象,其所占空间会随着内容的增加而扩充,这样,在做大量的修改操作时,不会因生成大量匿名对象而影响系统性能。
var sb = new StringBuilder("Hello");
String是不可变类,StringBuilder是可变类。
字符串格式
$前缀
string si = "World";
string s2 = $"Hello, {s1}“;
在现实中,这只是语法糖。对于带$前缀的字符串,编译器创建String.Format方法的调用。所以前面的代
码段解读为:
string si = "World";
string s2 = String.Format("Hello, {0}", si);
StringFormat
StringTormat方法的第一个参数接受一个格式字符串,其中的占位符从0开始编号,其后是放入字符串空白处的参数。新的字符串格式要方便得多,不需要编写那么多代码。
不仅可以使用变量来填写字符串的空白处,还可以使用返回一个值的任何方法:
string s2 = $”Hello, {si. ToUpper() } '*;
这段代码可解读为如下类似的语句:
string s2 = String.Format(nHello, {0}”,si.ToUpper ());
字符串还可以有多个空白处,如下所示的代码:
int x = 3, y = 4;
string s3 = $"MThe result of {x} + {y} is {x + y}'";
解读为:
string s3 = String.Format("The result of {0} and {1} is {2 } ", x, y, x + y);
转义花括号
如果希望在插值字符串中包括花括号,可以使用两个花括号转义它们:
string s = "Hello";
Console.WriteLine($"{{s}} displays the value of s: {s}");
WriteLine方法被解读为如下实现代码:
Console.WriteLine (String.Format (*'{s} displays the value of s: {0}", s));
输出如下:
{s} displays the value of s : Hello
还可以转义花括号,从格式字符串中建立一个新的格式字符串。下面看看这个代码段:
string formatstring = $" {s}, {{0 } } ";
string s2 = "World";
WriteLine(formatstring, s2);
有了字符串变量formatstring,编译器会把占位符0插入变量s,调用String.Format:
string formatstring = String. Format ("{0}, {{0} } ", s);
这会生成格式字符串,其中变量s替换为值Hello,删除第二个格式最外层的花括号:
string formatstring = "Hello, {0}";
在WriteLine方法的最后一行,使用变量s2的值把World字符串插值到新的占位符0中:
WriteLine("Hello, World");
日期时间和数字的格式
除了给占位符使用字符串格式之外,还可以根据数据类型使用特定的格式。下面先从日期开始。在占位符 中,格式字符串跟在表达式的后面,用冒号隔开。下面所示的例子是用于DateTime类型的D和d格式:
var day = new DateTime(2025, 2, 14);
WriteLine ($"{day:D}");
WriteLine ($"{day:d}”);
结果显示,用大写字母D表示长日期格式字符串,用小写字母d表示短日期字符串:
Friday, February 14, 2025
2/14/2025
应该提到的一个问题是,为DateTime构建自定义的格式字符串。自定义的日期和时间格式字符串可以结合 格式说明符,例如dd-MMM-yyyy:
Console.WriteLine($"{day:dd-MMM-yyyy}");
结果如下:
14-Feb-2025
这个自定义格式字符串利用dd把日期显示为两个数字(如果某个日期在10日之前,这就很重要,从这里可
以看到d和dd之间的区别)、MMM(月份的缩写名称,注意它是大写,而mm表示分钟)和表示四位数年份的yyyy。
数字的格式字符串不区分大小写。下面看看n、e、x和c标准数字格式字符串:
int i = 2477;
Console.WriteLine($"{i:n} {i:e} {i:x} {i:c}H);
n格式字符串定义了一个数字格式,用组分隔符显示整数和小数。e表示使用指数表示法,x表示转换为十
六进制,c显示货币:
2,477.00 2.477000e+003 9ad $2,477.00
对于数字的表示,还可以使用定制的格式字符串。#格式说明符是一个数字占位符,如果数字可用,就显示 数字;如果数字不可用,就不显示数字。0格式说明符是一个零占位符,显示相应的数字,如果数字不存在
正则表达式
正则表达式语言是一种专门用于字符串处理的语言。它包含两个功能:
- 一组用于标识特殊字符类型的转义代码。你可能很熟悉DOS命令中使用字符表示任意子字符串(例如, DOS命令DirRe会列出名称以Re开头的所有文件)。正则表达式使用与*类似的许多序列来表示“任 意一个字符”、“一个单词的中断”和个可选的字符”等。一个系统,在搜索操作中把子字符串和中1:司结果的各个部分组合起来。
- 识别(可以是标记或删除)字符串中所有重复的单词,例如,把“The computer books books”转换为“The computer books"
const string text =
"Professional C# 6 and .NET Core 1.0 provides complete coverage " +
"of the latest updates, features, and capabilities, giving you " +
"everything you need for C#. Get expert instruction on the latest " +
"changes to Visual Studio 2015, Windows Runtime, ADO.NET, ASP.NET, " +
"Windows Store Apps, Windows Workflow Foundation, and more, with " +
"clear explanations, no-nonsense pacing, and valuable expert insight. " +
"This incredibly useful guide serves as both tutorial and desk " +
"reference, providing a professional-level review of C# architecture " +
"and its application in a number of areas. You'll gain a solid " +
"background in managed code and .NET constructs within the context of " +
"the 2015 release, so you can get acclimated quickly and get back to work.";
Console.WriteLine("Find1\n");
const string pattern = "ion";
MatchCollection matches = Regex.Matches(text, pattern,
RegexOptions.IgnoreCase |
RegexOptions.ExplicitCapture);
WriteMatches(text, matches);
Console.WriteLine();
在这段代码中,使用了 System.Text.RegularExpressions名称空间中Regex类的静态方法Matches()0这个方 法的参数是一些输入文本、一个模式和从RegexOptions枚举中提取的一组可选标志.
表描述了 RegexOptions枚举的一些成员。
正则匹配主要符号规则如下:
组
在默认情况下,把模式的一部分组合为一个组时,就要求正则表达式引
擎按照该组来匹配,或按照整个模式来匹配。换言之,可以把组当成一个要匹配和返回的模式。如果要把字符 串分解为各个部分,这种模式就非常有效。
public static void NamedGroups()
{
Console.WriteLine("NamedGroups\n");
string line = "Hey, I've just found this amazing URI at http:// what was it --oh yes https://www.wrox.com or http://www.wrox.com:80";
string pattern = @"\b(?<protocol>https?)(?:://)(?<address>[.\w]+)([\s:](?<port>[\d]{2,4})?)\b";
Regex r = new Regex(pattern, RegexOptions.ExplicitCapture);
MatchCollection mc = r.Matches(line);
foreach (Match m in mc)
{
Console.WriteLine($"match: {m} at {m.Index}");
foreach (var groupName in r.GetGroupNames())
{
Console.WriteLine($"match for {groupName}: {m.Groups[groupName].Value}");
}
Console.WriteLine();
}
Console.WriteLine();
}
更多推荐
所有评论(0)