ImageVerifierCode 换一换
格式:DOCX , 页数:27 ,大小:35.75KB ,
资源ID:11358462      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11358462.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(第8章字符串和正则表达式.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

第8章字符串和正则表达式.docx

1、第8章 字符串和正则表达式第8章 字符串和正则表达式在本书的第一部分,我们一直在使用字符串,并说明C#中string关键字的映射实际上指向.NET 基类System.String。System.String是一个功能非常强大且用途非常广泛的基类,但它不是.NET中唯一与字符串相关的类。本章首先复习一下System.String的特性,再介绍如何使用其他的.NET类来处理字符串,特别是System.Text 和 System.Text.Regular Expressions命名空间中的类。本章主要介绍下述内容:创建字符串:如果多次修改一个字符串,例如,在显示字符串或将其传递给其他方法或应用程序前

2、,创建一个较长的字符串,String类就会变得效率低下。对于这种情况,应使用另一个类System.Text.StringBuilder,因为它是专门为这种情况设计的。格式化表达式:这些表达式将用于后面几章中的Console.WriteLine()方法。格式化表达式使用两个有效的接口IFormatProvider和IFormattable来处理。在自己的类上执行这两个接口,就可以定义自己的格式化序列,这样,Console.WriteLine()和类似的类就可以以指定的方式显示类的值。正则表达式:.NET还提供了一些非常复杂的类来识别字符串,或从长字符串中提取满足某些复杂条件的子字符串。例如,找出

3、字符串中重复出现的某个字符或一组字符,或者找出以s开头、且至少包含一个n的所有单词,或者找出遵循雇员ID或社会安全号码约定的字符串。虽然可以使用String类,编写方法来执行这类处理,但这类方法编写起来比较繁琐,而使用System.Text.RegularExpressions命名空间中的类就比较简单,System.Text. RegularExpressions专门用于执行这类处理。8.1 System.String类在介绍其他字符串类之前,先快速复习一下String类上一些可用的方法。System.String是一个类,专门用于存储字符串,允许对字符串进行许多操作。由于这种数据类型非常重要

4、,C#提供了它自己的关键字和相关的语法,以便于使用这个类来处理字符串。使用运算符重载可以连接字符串:string message1 = Hello; /return Hellomessage1 += , There; / return Hello, There string message2 = message1 + !; / return Hello, There!C#还允许使用类似于索引器的语法来提取指定的字符:char char4 = message4; / returns a. Note the char is zero-indexed这个类可以完成许多常见的任务,例如替换字符、删除空

5、白和把字母变成大写形式等。可用的方法如表8-1所示。表 8-1方 法作 用Compare比较字符串的内容,考虑文化背景(区域),确定某些字符是否相等CompareOrdinal与Compare一样,但不考虑文化背景Concat把多个字符串实例合并为一个实例CopyTo把特定数量的字符从选定的下标复制到数组的一个全新实例中Format格式化包含各种值的字符串和如何格式化每个值的说明符IndexOf定位字符串中第一次出现某个给定子字符串或字符的位置IndexOfAny定位字符串中第一次出现某个字符或一组字符的位置Insert把一个字符串实例插入到另一个字符串实例的指定索引处Join合并字符串数组,

6、建立一个新字符串LastIndexOf与IndexOf一样,但定位最后一次出现的位置 LastIndexOfAny与IndexOfAny,但定位最后一次出现的位置PadLeft在字符串的开头,通过添加指定的重复字符填充字符串PadRight在字符串的结尾,通过添加指定的重复字符填充字符串Replace用另一个字符或子字符串替换字符串中给定的字符或子字符串Split在出现给定字符的地方,把字符串拆分为一个子字符串数组Substring在字符串中获取给定位置的子字符串ToLower把字符串转换为小写形式ToUpper把字符串转换为大写形式Trim删除首尾的空白注意:这个表并不完整,但可以让您明白字

7、符串所提供的功能。8.1.1 创建字符串如上所述,string类是一个功能非常强大的类,它执行许多很有用的方法。但是,string类存在一个问题:重复修改给定的字符串,效率会很低,它实际上是一个不可变的数据类型,一旦对字符串对象进行了初始化,该字符串对象就不能改变了。表面上修改字符串内容的方法和运算符实际上是创建一个新的字符串,如果必要,可以把旧字符串的内容复制到新字符串中。例如,下面的代码:string greetingText = Hello from all the guys at Wrox Press. ;greetingText += We do hope you enjoy thi

8、s 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 th

9、e people at Wrox Press.复制到这个新字符串中,再加上额外的文本We do hope you enjoy this book as much as we enjoyed writing it.。然后更新存储在变量greetingText中的地址,使变量正确地指向新的字符串对象。旧的字符串对象被撤销了引用- 不再有变量引用它,下一次垃圾收集器清理应用程序中所有未使用的对象时,就会删除它。这本身还不坏,但假定要对这个字符串加密,在字母表中,用ASCII码中的字符替代其中的每个字母(标点符号除外),作为非常简单的加密模式的一部分,就会把该字符串变成Ifmmp gspn bmm u

10、if 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

11、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 +

12、 greetingText);注意:为了简单起见,这段代码没有把Z换成A,或把z换成a。这些字符分别编码为和。Replace()以一种智能化的方式工作,在某种程度上,它并没有创建一个新字符串,除非要对旧字符串进行某些改变。原来的字符串包含23个不同的小写字母,和3个不同的大写字母。所以Replace()就分配一个新字符串,共26次,每个新字符串都包含103个字符。因此加密过程需要在堆上有一个能存储总共2678个字符的字符串对象,最终将等待被垃圾收集!显然,如果使用字符串进行文字处理,应用程序就会有严重的性能问题。为了解决这个问题,Microsoft提供了System.Text.StringBu

13、ilder类。StringBuilder不像String那样支持非常多的方法。在StringBuilder上可以进行的处理仅限于替换和添加或删除字符串中的文本。但是,它的工作方式非常高效。在使用String类构造一个字符串时,要给它分配足够的内存来保存字符串,但StringBuilder通常分配的内存会比需要的更多。开发人员可以选择显式指定StringBuilder要分配多少内存,但如果没有显式指定,存储单元量在默认情况下就根据StringBuilder初始化时的字符串长度来确定。它有两个主要的属性:Length指定字符串的实际长度;Capacity是字符串占据存储单元的最大长度。对字符串的修

14、改就在赋予StringBuilder实例的存储单元中进行,这就大大提高了添加子字符串和替换单个字符的效率。删除或插入子字符串仍然效率低下,因为这需要移动随后的字符串。只有执行扩展字符串容量的操作,才需要给字符串分配新内存,才可能移动包含的整个字符串。在添加额外的容量时,从经验来看,StringBuilder如果检测到容量超出,且容量没有设置新值,就会使自己的容量翻倍。例如,如果使用StringBuilder对象构造最初的欢迎字符串,可以编写下面的代码:StringBuilder greetingBuilder =new StringBuilder(Hello from all the guys

15、 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亿个字符的空间(这

16、是StringBuilder实例允许拥有的最大理论空间),系统就可能会没有足够的内存。执行上面的代码,首先创建一个StringBuilder对象,如图8-1所示。图 8-1在调用Append()方法时,其他文本就放在空的空间中,不需要分配更多的内存。但是,多次替换文本才能获得使用StringBuilder所带来的性能提高。例如,如果要以前面的方式加密文本,就可以执行整个加密过程,无须分配更多的内存:StringBuilder greetingBuilder =new StringBuilder(Hello from all the guys at Wrox Press. , 150);gree

17、tingBuilder.Append(We do hope you enjoy this book as much as we + enjoyed writing it);Console.WriteLine(Not Encoded:n + greetingBuilder);for(int i = z; i=a ; i-)char old1 = (char)i;char new1 = (char)(i+1);greetingBuilder = greetingBuilder.Replace(old1, new1);for(int i = Z; i=A ; i- )char old1 = (cha

18、r)i;char new1 = (char)(i+1);greetingBuilder = greetingBuilder.Replace(old1, new1);Console.WriteLine(Encoded:n + greetingBuilder); 这段代码使用了StringBuilder.Replace()方法,它的功能与String.Replace()一样,但不需要在过程中复制字符串。在上述代码中,为存储字符串而分配的总存储单元是150个字符,用于StringBuilder实例以及在最后一个Console.WriteLine()语句中执行字符串操作期间分配的内存。一般,使用Str

19、ingBuilder可以执行字符串的操作,String可以存储字符串或显示最终结果。8.1.2 StringBuilder成员前面介绍了StringBuilder的一个构造函数,它的参数是一个初始字符串及该字符串的容量。还有几个其他的StringBuilder构造函数,例如,可以只提供一个字符串:StringBuilder sb = new StringBuilder(Hello);或者用给定的容量创建一个空的StringBuilder:StringBuilder sb = new StringBuilder(20);除了前面介绍的Length 和 Capacity属性外,还有一个只读属性Ma

20、xCapacity,它表示对给定的StringBuilder实例的容量限制。在默认情况下,这由int.MaxValue给定(大约20亿,如前所述)。但在构造StringBuilder对象时,也可以把这个值设置为较低的值:/ This will both set initial capacity to 100, but the max will be 500./ Hence, this StringBuilder can never grow to more than 500 characters,/ otherwise it will raise exception if you try to

21、 do that.StringBuilder sb = new StringBuilder(100, 500);还可以随时显式地设置容量,但如果把这个值设置为低于字符串的当前长度,或者超出了最大容量,就会抛出一个异常:StringBuilder sb = new StringBuilder(Hello);sb.Capacity = 100;主要的StringBuilder方法如表8-2所示。表 8-2名 称作 用Append()给当前字符串添加一个字符串AppendFormat()添加特定格式的字符串Insert()在当前字符串中插入一个子字符串Remove()从当前字符串中删除字符Repla

22、ce()在当前字符串中,用某个字符替换另一个字符,或者用当前字符串中的一个子字符串替换另一字符串ToString()把当前字符串转换为System.String对象(在System.Object中被重写)表 8-2其中一些方法还有几种格式的重载方法。注意:AppendFormat()实际上会在调用Console.WriteLine()时调用,它负责确定所有像0:D的格式化表达式应使用什么表达式替代。下一节讨论这个问题。不能把StringBuilder转换为String(隐式转换和显式转换都不行)。如果要把StringBuilder的内容输出为String,唯一的方式是使用ToString()方

23、法。前面介绍了StringBuilder类,说明了使用它提高性能的一些方式。注意,这个类并不总能提高性能。StringBuilder类基本上应在处理多个字符串时使用。但如果只是连接两个字符串,使用System.String会比较好。8.1.3 格式化字符串前面的代码示例中编写了许多类和结构,对这些类和结构执行ToString()方法,都是为了显示给定变量的内容。但是,用户常常希望以各种可能的方式显示变量的内容,在不同的文化或地区背景中有不同的格式。.NET基类System.DateTime就是最明显的一个示例:可以把日期显示为10 June 2008、10 Jun 2008、6/10/08 (

24、美国)、10/6/08 (英国)或10.06.2008 (德国)。同样,第6章中编写的Vector结构执行Vector.ToString()方法,是为了以(4, 56, 8)格式显示矢量。编写矢量的另一个非常常用的方式是4i + 56j + 8k。如果要使类的用户友好性比较高,就需要使用某些工具以用户希望的方式显示它们的字符串表示。.NET运行库定义了一种标准方式:使用接口IFormattable,本节的主题就是说明如何把这个重要特性添加到类和结构上。在显示一个变量时,常常需要指定它的格式,此时我们经常调用Console.WriteLine()方法。因此,我们把这个方法作为示例,但这里的讨论适

25、用于格式化字符串的大多数情况。例如,如果要在列表框或文本框中显示一个变量的值,一般要使用String.Format()方法来获得该变量的合适字符串表示,但用于请求所需格式的格式说明符与传递给Console.WriteLine()的格式相同,因此本节把Console.WriteLine()作为一个示例来说明。首先看看在为基本类型提供格式字符串时会发生什么,再看看如何把自己的类和结构的格式说明符添加到过程中。第2章在Console.Write()和Console.WriteLine()中使用了格式字符串:double d = 13.45;int i = 45;Console.WriteLine(T

26、he double is 0,10:E and the int contains 1, d, i);格式字符串本身大都由要显示的文本组成,但只要有要格式化的变量,它在参数列表中的下标就必须放在括号中。在括号中还可以有与该项的格式相关的其他信息,例如可以包含:该项的字符串表示要占用的字符数,这个信息的前面应有一个逗号,负值表示该项应左对齐,正值表示该项应右对齐。如果该项占用的字符数比给定的多,其内容也会完整地显示出来。格式说明符也可以显示出来。它的前面应有一个冒号,表示应如何格式化该项。例如,把一个数字格式化为货币,或者以科学计数法显示。第2章简要介绍了数字类型的常见格式说明符,表8-3再次引用

27、该表。表 8-3格 式 符应 用含 义示 例C数字类型 专用场合的货币值$4834.50 (USA)4834.50 (UK)D只用于整数类型一般的整数4834E数字类型科学计数法4.834E+003F数字类型小数点后的位数固定4384.50G数字类型一般的数字4384.5N数字类型通常是专用场合的数字格式4,384.50 (UK/USA)4 384,50 (欧洲大陆)P数字类型百分比计数法432,000.00%X只用于整数类型十六进制格式1120 (如果要显示0x1120,需要写上0x)如果要在整数上加上前导0,可以将格式说明符0重复所需的次数。例如,格式说明符0000会把3显示为0003,9

28、9显示为0099。这里不能给出完整的列表,因为其他数据类型有自己的格式说明符。本节的主要目的是说明如何为自己的类定义格式说明符。1. 字符串的格式化为了说明如何格式化字符串,看看执行下面的语句会得到什么结果:Console.WriteLine(The double is 0,10:E and the int contains 1, d, i);Console.WriteLine()只是把参数的完整列表传送给静态方法String.Format(),如果要在字符串中以其他方式格式化这些值,例如显示在一个文本框中,也可以调用这个方法。带有3个参数的WriteLine()重载方法如下:/ Likely

29、 implementation of Console.WriteLine()public void WriteLine(string format, object arg0, object arg1)Console.WriteLine(string.Format(format, arg0, arg1);上面的代码依次调用了带有1个参数的重载方法WriteLine(),仅显示了传递过来的字符串的内容,没有对它进行进一步的格式化。String.Format()现在需要用对应对象的合适字符串表示来替换每个格式说明符,构造最终的字符串。但是,如前所述,对于这个建立字符串的过程,需要StringBuil

30、der实例,而不是String实例。在这个示例中,StringBuilder实例是用字符串的第一部分(即文本The double is)创建和初始化的。然后调用StringBuilder.AppendFormat()方法,传递第一个格式说明符0,10:E和相应的对象double,把这个对象的字符串表示添加到构造好的字符串中,这个过程会继续重复调用StringBuilder.Append()和StringBuilder.AppendFormat()方法,直到得到了全部格式化好的字符串为止。下面的内容比较有趣。StringBuilder.AppendFormat()需要指出如何格式化对象,它首先检

31、查对象,确定它是否执行System命名空间中的接口IFormattable。只要试着把这个对象转换为接口,看看转换是否成功即可,或者使用C#关键字is,也能实现此测试。如果测试失败,AppendFormat()只会调用对象的ToString()方法,所有的对象都从System.Object继承了这个方法或重写了该方法。在前面给出的编写各种类和结构的示例中,执行过程都是这样,因为我们编写的类都没有执行这个接口。这就是在前面的章节中,Object.ToString()的重写方法允许在Console.WriteLine()语句中显示类和结构如Vector的原因。但是,所有预定义的基本数字类型都执行这个接口,对于这些类型,特别是这个示例中的double和int,就不会调用继承自System.Object的基

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1