没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论












目 录
第 8 章 字符串和正则表达式 .........................................................................................................2
8.1 System.String 类.................................................................................................................2
8.1.1 创建字符串 ..............................................................................................................3
8.1.2 StringBuilder 成员 ....................................................................................................5
8.1.3 格式化字符串 ..........................................................................................................6
8.2 正则表达式 ..................................................................................................................... 11
8.2.1 正则表达式概述 ..................................................................................................... 11
8.2.2 RegularExpressionsPlayaround 示例 ......................................................................... 11
8.2.3 显示结果 ............................................................................................................... 14
8.2.4 匹配、组合和捕获 ................................................................................................. 15
8.3 小结 ................................................................................................................................ 16

第 8 章 字符串和正则表达式
在本书的第一部分, 我们一直在使用字符串, 并说明 C#中 string 关键字的映射实际上指向 .NET 基
类 System.String。System.String 是一个功能非常强大且用途非常广泛的基类, 但它不是 .NET 中唯一与
字符串相关的类。本章首先复习一下 System.String 的特性,再介绍如何使用其他的 .NET 类来处理字
符串,特别是 System.Text 和 System.Text.Regular Expressions 命名空间中的类。本章主要介绍下述内
容:
●创建字符串:如果多次修改一个字符串,例如,在显示字符串或将其传递给其他方法或应用程
序前,创建一个较长的字符串, String 类就会变得效率低下。对于这种情况,应使用另 一个类
System.Text.StringBuilder ,因为它是专门为这种情况设计的。
●格式化表达式:这些表达式将用于后面几章中的 Console.WriteLine() 方法。格式化表达式使用
两个有效的接口 IFormatProvider 和 IFormattable 来处理。在自己的类上执行这两个接口,就可以定义
自己的格式化序列,这样, Console.WriteLine() 和类似的类就可以以指定的方式显示类的值。
●正则表达式: .NET 还提供了一些非常复杂的类来识别字符串,或从长字符串中提取满足某些
复杂条件的子字符串。例如,找出字符串中重复出现的某个字符或一组字符,或者找出以 s 开头、且
至少包含一个 n 的所有单词, 或者找出遵循雇员 ID 或社会安全号码约定的字符串。 虽然可以使用 String
类,编写方法来执行这类处理, 但这类方法编写起来比较繁琐, 而使用 System.Text.RegularExpressions
命名空间中的类就比较简单, System.Text. RegularExpressions 专门用于执行这类处理。
8.1 System.String 类
在介绍其他字符串类之前,先快速复习一下 String 类上一些可用的方法。
System.String 是一个类,专门用于存储字符串,允许对字符串进行许多操作。由于这种数据类型
非常重要, C#提供了它自己的关键字和相关的语法,以便于使用这个类来处理字符串。
使用运算符重载可以连接字符串:
string message1 = "Hello"; //return "Hello"
message1 += ", There"; // return "Hello, There "
string message2 = message1 + "!"; // return "Hello, There!"
C#还允许使用类似于索引器的语法来提取指定的字符:
char char4 = message[4]; // returns 'a'. Note the char is
zero-indexed
这个类可以完成许多常见的任务,例如替换字符、删除空白和把字母变成大写形式等。可用的方
法如表 8-1 所示。
表 8-1
方 法 作 用
Compare
比较字符串的内容,考虑文化背景 (区域 ),确定某些字符是否相等
CompareOrdinal
与 Compare 一样,但不考虑文化背景
Concat
把多个字符串实例合并为一个实例
CopyTo
把特定数量的字符从选定的下标复制到数组的一个全新实例中
Format
格式化包含各种值的字符串和如何格式化每个值的说明符
IndexOf
定位字符串中第一次出现某个给定子字符串或字符的位置
IndexOfAny
定位字符串中第一次出现某个字符或一组字符的位置
Insert
把一个字符串实例插入到另一个字符串实例的指定索引处
Join
合并字符串数组,建立一个新字符串
LastIndexOf
与 IndexOf 一样,但定位最后一次出现的位置

LastIndexOfAny
与 IndexOfAny ,但定位最后一次出现的位置
PadLeft
在字符串的开头,通过添加指定的重复字符填充字符串
PadRight
在字符串的结尾,通过添加指定的重复字符填充字符串
Replace
用另一个字符或子字符串替换字符串中给定的字符或子字符串
Split
在出现给定字符的地方,把字符串拆分为一个子字符串数组
Substring
在字符串中获取给定位置的子字符串
ToLower
把字符串转换为小写形式
ToUpper
把字符串转换为大写形式
Trim
删除首尾的空白
注意:
这个表并不完整,但可以让您明白字符串所提供的功能。
8.1.1 创建字符串
如上所述, string 类是一个功能非常强大的类,它执行许多很有用的方法。但是, string 类存在一
个问题:重复修改给定的字符串,效率会很低,它实际上是一个不可变的数据类型,一旦对字符串对
象进行了初始化, 该字符串对象就不能改变了。 表面上修改字符串内容的方法和运算符实际上是创建
一个新的字符串,如果必要,可以把旧字符串的内容复制到新字符串中。例如,下面的代码:
string greetingText = "Hello from all the guys at Wrox Press. ";
greetingText += "We do hope you enjoy this book as much as we
enjoyed writing it.";
在执行这段代码时, 首先,创建一个 System.String 类型的对象, 并初始化为文本 "Hello from all the
guys at Wrox Press. "。注意句号后面有一个空格。此时 .NET 运行库会为该字符串分配足够的内存来
保存这个文本 (39 个字符 ),再设置变量 greetingText,表示这个字符串实例。
从语法上看,下一行代码是把更多的文本添加到字符串中。实际上并非如此,而是创建一个新字
符串实例,给它分配足够的内存,以保存合并起来的文本 (共 103 个字符 )。最初的文本 "Hello from all
the people at Wrox Press."复制到这个新字符串中, 再加上额外的文本 "We do hope you enjoy this book as
much as we enjoyed writing it."。然后更新存储在变量 greetingText 中的地址,使变量正确地指向新的
字符串对象。 旧的字符串对象被撤销了引用 -- 不再有变量引用它, 下一次垃圾收集器清理应用程序中
所有未使用的对象时,就会删除它。
这本身还不坏, 但假定要对这个字符串加密, 在字母表中, 用 ASCII 码中的字符替代其中的每个
字母 (标点符号除外 ),作为非常简单的加密模式的一部分,就会把该字符串变成 "Ifmmp gspn bmm uif
hvst bu Xspy Qsftt. Xf ep ipqf zpv fokpz uijt cppl bt nvdi bt xf fokpzfe xsjujoh ju." 。完成这个任务有好几
种方式,但最简单、最高效的一种 (假定只使用 String 类)是使用 String. Replace() 方法,把字符串中指
定的子字符串用另一个子字符串代替。使用 Replace(),加密文本的代码如下所示:
string greetingText = "Hello from all the guys at Wrox Press. ";
greetingText += "We do hope you enjoy this book as much as we
enjoyed writing it.";
for(int i = 'z'; i>='a' ; i--)
{
char old1 = (char)i;
char new1 = (char)(i+1);
greetingText = greetingText.Replace(old1, new1);
}
for(int i = 'Z'; i>='A' ; i--)
{

char old1 = (char)i;
char new1 = (char)(i+1);
greetingText = greetingText.Replace(old1, new1);
}
Console.WriteLine("Encoded:\n" + greetingText);
注意:
为了简单起见,这段代码没有把 Z 换成 A,或把 z 换成 a。这些字符分别编码为 [ 和{。
Replace()以一种智能化的方式工作,在某种程度上,它并没有创建一个新字符串,除非要对旧字
符串进行某些改变。 原来的字符串包含 23 个不同的小写字母, 和 3 个不同的大写字母。 所以 Replace()
就分配一个新字符串,共 26 次,每个新字符串都包含 103 个字符。因此加密过程需要在堆上有一个
能存储总共 2678 个字符的字符串对象,最终将等待被垃圾收集!显然,如果使用字符串进行文字处
理,应用程序就会有严重的性能问题。
为了解决这个问题, Microsoft 提供了 System.Text.StringBuilder 类。 StringBuilder 不像 String 那样
支持非常多的方法。在 StringBuilder 上可以进行的处理仅限于替换和添加或删除字符串中的文本。但
是,它的工作方式非常高效。
在使用 String 类构造一个字符串时,要给它分配足够的内存来保存字符串,但 StringBuilder 通常
分配的内存会比需要的更多。开发人员可以选择显式指定 StringBuilder 要分配多少内存,但如果没有
显式指定,存储单元量在默认情况下就根据 StringBuilder 初始化时的字符串长度来确定。它有两个主
要的属性:
● Length 指定字符串的实际长度;
● Capacity 是字符串占据存储单元的最大长度。
对字符串的修改就在赋予 StringBuilder 实例的存储单元中进行, 这就大大提高了添加子字符串和
替换单个字符的效率。删除或插入子字符串仍然效率低下,因为这需要移动随后的字符串。只有执行
扩展字符串容量的操作,才需要给字符串分配新内存,才可能移动包含的整个字符串。在添加额外的
容量时,从经验来看, StringBuilder 如果检测到容量超出,且容量没有设置新值,就会使自己的容量
翻倍。
例如,如果使用 StringBuilder 对象构造最初的欢迎字符串,可以编写下面的代码:
StringBuilder greetingBuilder =
new StringBuilder("Hello from all the guys at Wrox Press. ", 150);
greetingBuilder.AppendFormat("We do hope you enjoy this book as
much as we enjoyed
writing it");
注意:
为了使用 StringBuilder 类,需要在代码中引用 System.Text。
在这段代码中,为 StringBuilder 设置的初始容量是 150。最好把容量设置为字符串可能的最大长
度,确保 StringBuilder 不需要重新分配内存,因为其容量足够用了。理论上,可以设置尽可能大的数
字,足够给该容量传送一个 int,但如果实际上给字符串分配 20 亿个字符的空间 (这是 StringBuilder
实例允许拥有的最大理论空间 ),系统就可能会没有足够的内存。
执行上面的代码,首先创建一个 StringBuilder 对象,如图 8-1 所示。
图 8-1
在调用 Append() 方法时,其他文本就放在空的空间中,不需要分配更多的内存。但是,多次替换
文本才能获得使用 StringBuilder 所带来的性能提高。例如,如果要以前面的方式加密文本,就可以执
剩余16页未读,继续阅读
资源评论

cyh76339129
- 粉丝: 0
- 资源: 14万+

下载权益

C知道特权

VIP文章

课程特权

开通VIP

上传资源 快速赚钱
我的内容管理 收起
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助

会员权益专享
安全验证
文档复制为VIP权益,开通VIP直接复制
