C#基础知识之字符串和正则表达式
作者:sufengmarket
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, {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->si. ToUpper() } '*;
这段代码可解读为如下类似的语句:
string s2 = String.Format(nHello, {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->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 (*'{<!--{C}%3C!%2D%2D%20%2D%2D%3E-->s} displays the value of s: {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->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}, {<!--{C}%3C!%2D%2D%20%2D%2D%3E-->{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(); }
总结
到此这篇关于C#基础知识之字符串和正则表达式的文章就介绍到这了,更多相关C#字符串和正则表达式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!