C#中的正则表达式介绍
正则表达式的全面模式匹配表示法可以快速地分析大量的文本以找到特定的字符模式;提取、编辑、替换或删除文本子字符串;或将提取的字符串添加到集合以生成报告。
1、正则表达式简介
正则表达式提供了功能强大、灵活而又高效的方法来处理文本。正则表达式的全面模式匹配表示法可以快速地分析大量的文本以找到特定的字符模式;提取、编辑、替换或删除文本子字符串;或将提取的字符串添加到集合以生成报告。对于处理字符串(例如HTML处理、日志文件分析和HTTP标头分析)的许多应用程序而言,正则表达式是不可缺少的工具。
.NET框架正则表达式并入了其他正则表达式实现的最常见功能,被设计为与Perl5正则表达式兼容,.NET框架正则表达式还包括一些在其他实现中尚未提供的功能,.NET框架正则表达式类是基类库的一部分,并且可以和面向公共语言运行库的任何语言或工具一起使用。
2、字符串搜索
正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。正是元字符组为正则表达式提供了处理能力。当前,所有的文本编辑器都有一些搜索功能,通常可以打开一个对话框,在其中的一个文本框中键入要定位的字符串,如果还要同时进行替换操作,可以键入一个替换字符串,比如在Windows操作系统中的记事本、Office系列中的文档编辑器都有这种功能。
这种搜索最简单的方式,这类问题很容易用String类的String.Replace()方法来解决,但如果需要在文档中识别某个重复的,该怎么办?
编写一个例程,从一个String类中选择重复的字是比较复杂的,此时使用语言就很适合。
一般表达式语言是一种可以编写搜索表达式的语言。在该语言中,可以把文档中要搜索的文本、转义序列和特定含义的其他字符组合在一起,例如序列b表示一个字的开头和结尾(子的边界),如果要表示正在查找的以字符th开头的字,就可以编写一般表达式bth(即序列字符界是-t-h)。如果要搜索所有以th结尾的字,就可以编写thb(序列t-h-字边界)。但是,一般表达式要比这复杂得多,例如,可以在搜索操作中找到存储部分文本的工具性程序(facility)。
3、.NET框架的正则表达式类
下面通过介绍.NET框架的正则表达式类,熟悉一下.NET框架下的正则表达式的使用方法。
3.1Regex类表示只读正则表达式
Regex类包含各种静态方法,允许在不显式实例化其他类的对象的情况下使用其他正则表达式类。以下代码示例创建了Regex类的实例并在初始化对象时定义一个简单的正则表达式。请注意,使用了附加的反斜杠作为转义字符,它将s匹配字符类中的反斜杠指定为原义字符。
Regexr;//声明一个Regex类的变量 r=newRegex("\s2000");//定义表达式
3.2Match类表示正则表达式匹配操作的结果
以下示例使用Regex类的Match方法返回Match类型的对象,以便找到输入字符串中第一个匹配。此示例使用Match类的Match.Success属性来指示是否已找到匹配。
Regexr=newRegex("abc");//定义一个Regex对象实例 Matchm=r.Match("123abc456");//在字符串中匹配 if(m.Success) { Console.WriteLine("Foundmatchatposition"+m.Index);//输入匹配字符的位置 }
3.3MatchCollection类表示非重叠匹配的序列
该集合为只读的,并且没有公共构造函数。MatchCollection的实例是由Regex.Matches属性返回的。使用Regex类的Matches方法,通过在输入字符串中找到的所有匹配填充MatchCollection。下面代码示例演示了如何将集合复制到一个字符串数组(保留每一匹配)和一个整数数组(指示每一匹配的位置)中。
MatchCollectionmc; String[]results=newString[20]; int[]matchposition=newint[20]; Regexr=newRegex("abc");//定义一个Regex对象实例 mc=r.Matches("123abc4abcd"); for(inti=0;i<mc.Count;i++)//在输入字符串中找到所有匹配 { results=mc.Value;//将匹配的字符串添在字符串数组中 matchposition=mc.Index;//记录匹配字符的位置 }
3.4GroupCollection类表示捕获的组的集合
该集合为只读的,并且没有公共构造函数。GroupCollection的实例在Match.Groups属性返回的集合中返回。下面的控制台应用程序查找并输出由正则表达式捕获的组的数目。
usingSystem; usingSystem.Text.RegularExpressions; publicclassRegexTest { publicstaticvoidRunTest() { Regexr=newRegex("(a(b))c");//定义组 Matchm=r.Match("abdabc"); Console.WriteLine("Numberofgroupsfound="+m.Groups.Count); } publicstaticvoidMain() { RunTest(); } }
该示例产生下面的输出:
Numberofgroupsfound=3
3.5CaptureCollection类表示捕获的子字符串的序列
由于限定符,捕获组可以在单个匹配中捕获多个字符串。Captures属性(CaptureCollection类的对象)是作为Match和group类的成员提供的,以便于对捕获的子字符串的集合的访问。例如,如果使用正则表达式((a(b))c)+(其中+限定符指定一个或多个匹配)从字符串"abcabcabc"中捕获匹配,则子字符串的每一匹配的Group的CaptureCollection将包含三个成员。
下面的程序使用正则表达式(Abc)+来查找字符串"XYZAbcAbcAbcXYZAbcAb"中的一个或多个匹配,阐释了使用Captures属性来返回多组捕获的子字符串。
usingSystem; usingSystem.Text.RegularExpressions; publicclassRegexTest { publicstaticvoidRunTest() { intcounter; Matchm; CaptureCollectioncc; GroupCollectiongc; Regexr=newRegex("(Abc)+");//查找"Abc" m=r.Match("XYZAbcAbcAbcXYZAbcAb");//设定要查找的字符串 gc=m.Groups; //输出查找组的数目 Console.WriteLine("Capturedgroups="+gc.Count.ToString()); //Loopthrougheachgroup. for(inti=0;i<gc.Count;i++)//查找每一个组 { cc=gc.Captures; counter=cc.Count; Console.WriteLine("Capturescount="+counter.ToString()); for(intii=0;ii<counter;ii++) { //Printcaptureandposition. Console.WriteLine(cc[ii]+"Startsatcharacter"+ cc[ii].Index);//输入捕获位置 } } } publicstaticvoidMain(){ RunTest(); } }
此例返回下面的输出结果:
Capturedgroups=2 Capturescount=1 AbcAbcAbcStartsatcharacter3 Capturescount=3 AbcStartsatcharacter3 AbcStartsatcharacter6 AbcStartsatcharacter9
3.6Capture类包含来自单个子表达式捕获的结果
在Group集合中循环,从Group的每一成员中提取Capture集合,并且将变量posn和length分别分配给找到每一字符串的初始字符串中的字符位置,以及每一字符串的长度。
Regexr; Matchm; CaptureCollectioncc; intposn,length; r=newRegex("(abc)*"); m=r.Match("bcabcabc"); for(inti=0;m.Groups.Value!="";i++) { cc=m.Groups.Captures; for(intj=0;j<cc.Count;j++) { posn=cc[j].Index;//捕获对象位置 length=cc[j].Length;//捕获对象长度 } }
把组合字符组合起来后,每次都会返回一个组对象,就可能并不是我们希望的结果。如果希望把组合字符作为搜索模式的一部分,就会有相当大的系统开销。对于单个的组,可以用以字符序列"?:"开头的组禁止这么做,就像URI样例那样。而对于所有的组,可以在RegEx.Matches()方法上指定RegExOptions.ExplicitCapture标志。
希望通过本文对正则表达式的介绍,能够给你带来帮助。