2009年4月28日星期二
.NET进阶学习;.NET学习;C#: C#教程(四十二)正则表达式(2)
staticvoidWriteMatches(stringtext,MatchCollectionmatches)
{
Console.WriteLine("Originaltextwas:\n\n"+text+"\n");
Console.WriteLine("No.ofmatches:"+matches.Count);
foreach(MatchnextMatchinmatches)
{
intIndex=nextMatch.Index;
stringresult=nextMatch.ToString();
intcharsBefore=(Index()方法
staticvoidMain()
{
Find1();
Console.ReadLine();
}
这段代码还使用了命名空间RegularExpressions
usingSystem;
usingSystem.Text.RegularExpressions;
运行带有Find1()方法的示例得到如下所示的结果
RegularExpressionsPlayaround
Originaltextwas:
Thiscomprehensivecompendiumprovidesabroadandthoroughinvestigationofall
aspectsofprogrammingwithASP.NET.Entityrevisedandupdatedforthe1.1
Releaseof.NET,thisbookwillgiveyoutheinformationyouneedtomasterASP.NET
Andbuildadynamic,successful,enterpriseWebapplication.
No.ofmatches:1
Index:291,String:application,Webapplication.
8.2.4匹配组合和捕获
正则表达式的一个很好的特性是可以把字符组合起来其方式与C#中的复合语句一样在C#中可以把任意数量的语句放在花括号中把它们组合在一起其结果就像一个复合语句那样在正则表达式模式中也可以把任何字符组合起来(包括元字符和转义序列)像处理一个字符那样处理它们惟一的区别是要使用圆括号而不是花括号得到的序列称为一个组
例如模式(an)+定位序列an的任意重复量词+只应用于它前面的一个字符但因为我们把字符组合起来了所以它现在把重复的an作为一个单元来对待(an)+应用到输入文本"bananascametoEuropelateintheannalsofhistory"上会从bananas中选择出anan另一方面如果使用an+则将从annals中选择ann从bananas中选择出两个an表达式an+可以提取出anananananan等而表达式an+可以提取出anannannn等
注意
在上面的示例中为什么(an)+从banana中选择的是anan而没有把单个的an作为一个匹配匹配规则是不能重叠的如果有可能重叠在默认情况下就选择较长的匹配
但是组的功能要比这强大得多在默认情况下把模式的一部分组合为一个组时就要求正则表达式引擎记住可以按照这个组来匹配也可以按照整个模式来匹配换言之可以把组当作一个要匹配的模式来返回如果要把字符串分解为各个部分这种模式就是非常有效的
例如URI的格式是
://:
其中端口是可选的它的一个示例是http://www.wrox.com:4355假定要从一个URI中提取协议地址和端口而且紧邻URI的后面可能有空白(但没有标点符号)就可以使用下面的表达式
\b(\S+)://(\S+)(?::(\S+))?\b
该表达式的工作方式如下首先前导和尾部的\b序列确保只需要考虑完全是字的文本部分在这个文本部分中第一组(\S+)://会选择一个或多个不是空白的字符其后是://在HTTPURI的开头会选择出http://花括号表示把http存储为一个组后面的序列(\S+)则在上述URI中选择www.wrox.com这个组在遇到词的结尾(结束\b)时或标记另一个组的冒号()时结束
下一个组选择端口(本例是:4355)后面的表示这个组在匹配中是可选的如果没有:xxxx也不会妨碍匹配的标记这是非常重要的因为端口号在URI中一般不指定实际上在大多数情况下URI是没有端口号的但是事情会比较复杂我们希望指定冒号可以出现也可以不出现但不希望把这个冒号也存储在组中为此可以嵌套两个组内部的(\S+)组选择冒号后面的内容(本例中是4355)外面的组包含内部的组后面是一个冒号该冒号又在序列?:的后面这个序列表示该组不应保存(只需要保存4355不需要保存:4355)不要把这两个冒号混淆了第一个冒号是序列?:的一部分表示不保存这个组第二个冒号是要搜索的文本
在下面的字符串上运行该模式得到的匹配是http://www.wrox.com
HeyI'vejustfoundthisamazingURIathttp://whatwasitohyeshttp://www.wrox.com
在这个匹配中找到了3个组还有第四个组表示匹配本身理论上每个组都可以选择0次1次或多次匹配单个的匹配就称为捕获在第一个组(\S+)中有一个捕获http第二个组也有一个捕获www.wrox.com但第三个组没有捕获因为在这个URI中没有端口号
注意该字符串包含第二个http://虽然它匹配于第一个组但不会被搜索出来因为整个搜索表达式不匹配于这部分文本
前面没有介绍使用组和捕获的任何C#示例下面提到的.NET类RegularExpressions就通过Group和Capture类支持组和捕获GroupCollection和CaptureCollection分别表示组和捕获的集合Match类有一个方法Groups()它返回相应的GroupCollection对象Group类也相应地执行一个方法Captures()它返回CaptureCollection对象对象之间的关系如图8-3所示
图8-3
订阅:
博文评论 (Atom)
0 评论:
发表评论