括号

  正则表达式中的括号能将多个字符或者表达式当做一组,即将他们看成一个整体。这样量词就可以修饰这一组表达式。阅读本章前,建议先下载我于CSDN上传的示例代码,下载无需分数,下载链接

1.分组

  假设我们要匹配偶数个数字,如何匹配?尝试"^\d{2}+$"来匹配。"\d{2}"匹配2个数字,"+"匹配至少一次,两者组合起来应该是偶数个数字。但是由下例可看出这个正则表达式并不合法。只能尝试修改这个正则表达式为"^(\d{2})+$"。将"\d{2}"看做一个分组,再来使用量词。

Regex.IsMatch("12",@"^\d{2}+$");
//抛出异常:System.ArgumentException
//异常信息:正在分析“^\d{2}+$”- 嵌套限定符 +。
Regex.IsMatch("12",@"^(\d{2})+$");//true

 

2.捕获分组

  捕获分组十分有用,他可以捕获匹配正则表达式的子字符串。分组其实是带有捕获功能的,例如分组"(\d)"匹配呢数字"5",则可以通过匹配对象获得"5"这个值。现在有几个匹配日期格式的正则表达式"(\d{4}-\d{2}-\d{2})","(\d{4}-\d{2})-\d{2}","(\d{4})-(\d{2})-(\d{2})"和一个十分没有规律的输入字符串"2015-06-15-20-30-2014-02-28-01-015-2015-08-09-00"。我们要从中提取出一些日期,不同的正则表达式会让程序输出不同的结果,但是他们均会匹配出他们想要的三个日期。"2015-06-15","2014-02-28","2015-08-09"。

 1 //一个用于输出匹配子字符串的辅助方法
 2 public static void ShowAllMatch(Match match, bool isCapture)
 3 {
 4     int MatchCount = 0;//匹配次数
 5     while (true)
 6     {
 7         if (match.Success)
 8         {
 9             MatchCount++;
10             Console.WriteLine("第{0}个匹配的字符串为:{1}", MatchCount.ToString(), match.Value);
11             int GroupIndex = 0;
12             /*
13              * 对于任意一个Match对象,其Gruops集合中至少有一个元素,下标为0。
14              * 若Match对象能成功匹配子字符串,则下标0的位置默认存储整个匹配的字符串。若不成功则为空。
15              * 若通过下标寻找不存在的项,则只返回空字符串,不会报错。
16              * 其余下标对应正则表达式中括号出现的位置。如第一个Gruops[1],对应匹配第一个括号的分组。
17              */
18             foreach (Group group in match.Groups)
19             {
20                 Console.WriteLine("分组下标:{0},分组的值为:{1}", GroupIndex.ToString(), group.Value);
21                 /*
22                  * 当在括号分组后加上量词时(如'(\d){m,n}'这种形式),可通过Capture类获得每一次捕获的字符串。
23                  * 如,若匹配了字符串"2015",则Capture会分别捕获,"2","0","1","5",group.Value的值为"5"
24                  * 此时,group.Value仅获取最后捕获的子字符串。
25                  */
26                 if (isCapture)
27                 {
28                     int CaptureIndex = 0;
29                     foreach (Capture capture in group.Captures)
30                     {
31                         Console.WriteLine("分组下标:{0},第{1}个捕获的子字符串为:{2}", GroupIndex.ToString(), CaptureIndex.ToString(), capture.Value);
32                         CaptureIndex++;
33                     }
34                 }
35                 GroupIndex++;
36             }
37             match = match.NextMatch();//获取从该匹配位置结束之后的下一个匹配对象。
38             Console.WriteLine();
39         }
40         else
41         {
42             if (MatchCount == 0)
43                 Console.WriteLine("没有匹配项!");
44             else
45                 Console.WriteLine("匹配结束!");
46             break;
47         }
48     }
49 }
50 
51 /*Main方法中的调用*/
52 
53 Console.WriteLine("---捕获分组示例1---");
54 string InputB = "2015-06-15-20-30-2014-02-28-01-015-2015-08-09-00";
55 string RegexStrB = @"(\d{4})-(\d{2})-\d{2}";//匹配一个日期,格式为YYYY-MM-DD。再通过分组获取匹配字符串中的年份和月份。
56 Regex RegexB = new Regex(RegexStrB);
57 Match MatchB = RegexB.Match(InputB);
58 ShowAllMatch(MatchB, false);
59 Console.WriteLine();
60 
61 Console.WriteLine("---捕获分组示例2---");
62 string InputC = "2015-06-15-20-30-2014-02-28-01-015-2015-08-09-00";
63 string RegexStrC = @"(\d){4}-(\d){2}-\d{2}";//匹配一个日期,格式为YYYY-MM-DD。再通过分组获取匹配字符串中的年份和月份。
64 Regex RegexC = new Regex(RegexStrC);
65 Match MatchC = RegexC.Match(InputC);
66 ShowAllMatch(MatchC, true);
67 Console.WriteLine();
68 
69 Console.WriteLine("---捕获分组示例3---");
70 string InputD = "2015-06-15-20-30-2014-02-28-01-015-2015-08-09-00";
71 /*
72  * 匹配一个日期,格式为YYYY-MM-DD。再通过分组获取匹配字符串中的年份和月份。
73  * 若括号之间有嵌套,则Group的下标先算外层括号,再算内层。
74  */
75 string RegexStrD = @"((\d){4}-(\d){2})-(\d){2}";
76 Regex RegexD = new Regex(RegexStrD);
77 Match MatchD = RegexD.Match(InputD);
78 ShowAllMatch(MatchD, true);
79 Console.WriteLine();
View Code

相关文章: