C#基础知识之字符串和正则表达式的案例分享

2022-11-06 20:23:24 浏览数 (1)

String

System.String类专门用于存储字符串,允许对字符串进行许多操作。此外,由于这种数据类型非常重要,C# 提供了它自己的关键字和相关的语法,以便使用这个类来轻松地处理字符串。使用运算符重载可以连接字符串:

123

string messagel = ''Hello"; // returns "Hello" messagel = ”,There";   // returns "Hello, There"string message2 = messagel "!";  // returns "Hello, There! "

c#还允许使用类似于索引器的语法来提取指定的字符:

12

string message = ''Hello”;char char4 = message[4]; // returns "0"

这个类可以完成许多常见的任务,如替换字符、删除空白和把字母变成大写形式等。

string 和 stringbuilder

String类是一个功能非常强大的类,它实现许多很有用的方法。但是,String类存在一个问题: 重复修改给定的字符串,效率会很低,它实际上是一个不可变的数据类型,这意味着一旦对字符串对象进行了 初始化,该字符串对象就不能改变了。

12

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类则不同,每次操作都是对自身对象进行操作,而不是生成新的对象,其所占空间会随着内容的增加而扩充,这样,在做大量的修改操作时,不会因生成大量匿名对象而影响系统性能。

1

var sb = new StringBuilder("Hello");

String是不可变类,StringBuilder是可变类。

字符串格式

$前缀

12

string si = "World"; string s2 = $"Hello, {s1}“;

在现实中,这只是语法糖。对于带$前缀的字符串,编译器创建String.Format方法的调用。所以前面的代码段解读为:

12

string si = "World";string s2 = String.Format("Hello, {0}", si);

StringFormat

StringTormat方法的第一个参数接受一个格式字符串,其中的占位符从0开始编号,其后是放入字符串空白处的参数。新的字符串格式要方便得多,不需要编写那么多代码。

不仅可以使用变量来填写字符串的空白处,还可以使用返回一个值的任何方法:

1

string s2 = $”Hello, {<!--{C}-->si. ToUpper() } '*;

这段代码可解读为如下类似的语句:

1

string s2 = String.Format(nHello, {<!--{C}-->0}”,si.ToUpper ());

字符串还可以有多个空白处,如下所示的代码:

12

int x = 3, y = 4;string s3 = $"MThe result of {x} {y}  is {x y}'";

解读为:

1

string s3 = String.Format("The result of {0} and {1} is {2 } ", x, y, x y);

转义花括号

如果希望在插值字符串中包括花括号,可以使用两个花括号转义它们:

12

string s = "Hello";Console.WriteLine($"{{s}}  displays the value of s:   {s}");

WriteLine方法被解读为如下实现代码:

1

Console.WriteLine (String.Format (*'{<!--{C}-->s} displays the value of s: {<!--{C}-->0}", s));

输出如下:

{s}   displays the value of s :    Hello

还可以转义花括号,从格式字符串中建立一个新的格式字符串。下面看看这个代码段:

123

string formatstring = $" {s},   {{0 } } "; string s2 = "World";WriteLine(formatstring, s2);

有了字符串变量formatstring,编译器会把占位符0插入变量s,调用String.Format:

1

string formatstring = String. Format ("{0}, {<!--{C}-->{0} } ", s);

这会生成格式字符串,其中变量s替换为值Hello,删除第二个格式最外层的花括号:

1

string formatstring = "Hello, {0}";

在WriteLine方法的最后一行,使用变量s2的值把World字符串插值到新的占位符0中:

1

WriteLine("Hello, World");

日期时间和数字的格式

除了给占位符使用字符串格式之外,还可以根据数据类型使用特定的格式。下面先从日期开始。在占位符 中,格式字符串跟在表达式的后面,用冒号隔开。下面所示的例子是用于DateTime类型的D和d格式:

123

var day = new DateTime(2025, 2, 14); WriteLine ($"{day:D}");WriteLine ($"{day:d}”);

结果显示,用大写字母D表示长日期格式字符串,用小写字母d表示短日期字符串:

12

Friday, February 14, 2025 2/14/2025

应该提到的一个问题是,为DateTime构建自定义的格式字符串。自定义的日期和时间格式字符串可以结合 格式说明符,例如dd-MMM-yyyy:

1

Console.WriteLine($"{day:dd-MMM-yyyy}");

结果如下:

14-Feb-2025

这个自定义格式字符串利用dd把日期显示为两个数字(如果某个日期在10日之前,这就很重要,从这里可以看到d和dd之间的区别)、MMM(月份的缩写名称,注意它是大写,而mm表示分钟)和表示四位数年份的yyyy。

数字的格式字符串不区分大小写。下面看看n、e、x和c标准数字格式字符串:

12

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"

1

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("Find1n");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枚举的一些成员。

正则匹配主要符号规则如下:

在默认情况下,把模式的一部分组合为一个组时,就要求正则表达式引擎按照该组来匹配,或按照整个模式来匹配。换言之,可以把组当成一个要匹配和返回的模式。如果要把字符 串分解为各个部分,这种模式就非常有效。

2

public static void NamedGroups(){     Console.WriteLine("NamedGroupsn");     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 人点赞