解读c#中的正则表达式_c#应用

2008-02-23 05:44:31来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

作者:刘彦青  

多少年来,许多的编程语言和工具都包含对正则表达式的支持,.NET基础类库中包含有一个名字空间和一系列能够充分发挥规则表达式威力的类,而且他们也都和未来的Perl 5中的规则表达式兼容。

  此外,regexp类还能够完成一些其他的功能,例如从右至左的结合模式和表达式的编辑等。

  在这篇文章中,我将简要地介绍System.Text.RegularExpression中的类和方法、一些字符串匹配和替换的例子连同组结构的周详情况,最后,还会介绍一些您可能会用到的常见的表达式。

应该掌控的基础知识

  规则表达式的知识可能是不少编程人员“常学常忘”的知识之一。在这篇文章中,我们将假定您已掌控了规则表达式的用法,尤其是Perl 5中表达式的用法。.NET的regexp类是Perl 5中表达式的一个超集,因此,从理论上说他将作为一个很好的起点。我们还假设您具备了C#的语法和.NET架构的基本知识。

  假如您没有规则表达式方面的知识,我建议您从Perl 5的语法着手开始学习。在规则表达式方面的权威书籍是由杰弗里·弗雷德尔编写的《掌控表达式》一书,对于希望深刻理解表达式的读者,我们强烈建议阅读这本书。

RegularExpression组合体

  regexp规则类包含在System.Text.RegularExpressions.dll文档中,在对应用软件进行编译时您必须引用这个文档,例如:

csc r:System.Text.RegularExpressions.dll foo.cs

命令将创建foo.exe文档,他就引用了System.Text.RegularExpressions文档。

名字空间简介

  在名字空间中仅仅包含着6个类和一个定义,他们是:

  Capture: 包含一次匹配的结果;
  CaptureCollection: Capture的序列;
  Group: 一次组记录的结果,由Capture继承而来;
  Match: 一次表达式的匹配结果,由Group继承而来;
  MatchCollection: Match的一个序列;
  MatchEvaluator: 执行替换操作时使用的代理;
  Regex: 编译后的表达式的实例。

  Regex类中还包含一些静态的方法:

  Escape: 对字符串中的regex中的转义符进行转义;
  IsMatch: 假如表达式在字符串中匹配,该方法返回一个布尔值;
  Match: 返回Match的实例;
  Matches: 返回一系列的Match的方法;
  Replace: 用替换字符串替换匹配的表达式;
  Split: 返回一系列由表达式决定的字符串;
  Unescape:不对字符串中的转义字符转义。

简单匹配

  我们首先从使用Regex、Match类的简单表达式开始学习。

Match m = Regex.Match("abracadabra", "(a|b|r) ");

我们现在有了一个能够用于测试的Match类的实例,例如:if (m.Success)...
假如想使用匹配的字符串,能够把他转换成一个字符串:

Console.WriteLine("Match=" m.ToString());

这个例子能够得到如下的输出: Match=abra。这就是匹配的字符串了。

字符串的替换

  简单字符串的替换很直观。例如下面的语句:

string s = Regex.Replace("abracadabra", "abra", "zzzz");

他返回字符串zzzzcadzzzz,任何匹配的字符串都被替换成了zzzzz。

  现在我们来看一个比较复杂的字符串替换的例子:

string s = Regex.Replace(" abra ", @"^\s*(.*?)\s*$", "$1");

这个语句返回字符串abra,其前导和后缀的空格都去掉了。

  上面的模式对于删除任意字符串中的前导和后续空格都很有用。在C#中,我们还经常使用字母字符串,在一个字母字符串中,编译程式不把字符“ \” 作为转义字符处理。在使用字符“\”指定转义字符时,@"..."是很有用的。另外值得一提的是$1在字符串替换方面的使用,他表明替换字符串只能包含被替换的字符串。

匹配引擎的细节

  现在,我们通过一个组结构来理解一个稍微复杂的例子。看下面的例子:

string text = "abracadabra1abracadabra2abracadabra3";

  string pat = @"

    ( # 第一个组的开始

     abra # 匹配字符串abra

     ( # 第二个组的开始

     cad # 匹配字符串cad

     )? # 第二个组结束(可选)

    ) # 第一个组结束

     # 匹配一次或多次

    ";

  //利用x修饰符忽略注释

  Regex r = new Regex(pat, "x");

  //获得组号码的清单

  int[] gnums = r.GetGroupNumbers();

  //首次匹配

  Match m = r.Match(text);

  while (m.Success)

   {

  //从组1开始

   for (int i = 1; i < gnums.Length; i )

    {

    Group g = m.Group(gnums[i]);

  //获得这次匹配的组

    Console.WriteLine("Group" gnums[i] "=[" g.ToString() "]");

  //计算这个组的起始位置和长度

    CaptureCollection cc = g.Captures;

    for (int j = 0; j < cc.Count; j )

     {

     Capture c = cc[j];

     Console.WriteLine(" Capture" j "=[" c.ToString()

       "] Index=" c.Index " Length=" c.Length);

     }

    }

  //下一个匹配

   m = m.NextMatch();

   }

这个例子的输出如下所示:
     
  Group1=[abra]

      Capture0=[abracad] Index=0 Length=7

      Capture1=[abra] Index=7 Length=4

  Group2=[cad]

      Capture0=[cad] Index=4 Length=3

  Group1=[abra]

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 深入解析c#编程中的事件_c#应用

下一篇: 从internet上抓取指定url的源码的方案(c#)_c#应用