正则表达式 (Regular expressions) 是一套语法匹配规则,各种语言,如 Perl , .Net 和 Java 都有其对应的共享的正则表达式类库。在 .Net 中,这个类库叫做 Regex 。
简单的说, Regex 是从字符窗中查找匹配字符串的应用类。通过 Regex ,编程人员能够非常方便的从一段数据中提取自己所需要的数据信息。举一个简单的例子,让大家对 Regex 有个大概的了解:
Regex regex = new Regex(@"\d+");
Match m = regex.Match("fox 9212gold");
Console.WriteLine(m.Value.ToString());
结果很明显, regex 为我们找到了字符串 ”fox 9212gold” 中的数字字符串,输出结果为 ”9212” .
对 Regex 有了一个基本的概念之后,我需要告诉你一个非常好的消息,那就是 Regex 可以为我们做的远不止这么一点点,他是一套功能非常强大语法匹配规则。当然,这里还有一个坏消息等着我们,那就是强大功能的语法规则自然需要大量纷繁复杂的 keyword 支持,这也为 Regex 的学习带来了极大的难度。想要真正掌握正则表达式,可不是几个 sample 能够全部揭示与说明的。
创建一个 Regex 对象
Regex 的构造函数有三种,在这里就不讨论默认构造函数了。另外两个构造函数中,一个构造函数接收正则表达式字符串作为入参,另一个以正则表达式字符串和 RegexOptions 作为入参。如:
Regex regex = new Regex("\ w +$") ;
Regex regex = new Regex("\ s +", RegexOptions.IgnoreCase | RegexOptions.Multiline) ;
RegexOptions 可以为我们提供一些特殊的帮助,比如 IgnoreCase 能够在匹配是忽略大小写, Multiline 能够调整 ^ 和 $ 的意义,改为匹配一行的开头和结尾。
上面我们构造了一个正则表达式,只不过我们还没有用它来做任何事情,马上我们就可以通过使用下面的几个方法,实现对字符串对象的操作了。
匹配字符串
Regex 有两个获取匹配的方法 Match() 和 Matches() ,分别代表匹配一个,匹配多个结果。这里就用 Matches 来展示一下怎么使用 Regex 获取匹配字符串,并将其显示出来。
public static void showMatches( string expression, RegexOptions option, string ms)
{
Regex regex = new Regex(expression, option);
MatchCollection matches = regex.Matches(ms);
//show matches
Console.WriteLine("////////////////----------------------------------////////////////");
Console.WriteLine(" string: "{0}"\r\n expression: "{1}"\r\n match result is:",
ms, expression);
foreach (Match m in matches)
{ Console.WriteLine("match string is: "{0}", length: {1}",
m.Value.ToString(), m.Value.Length);
}
Console.WriteLine("matched count: {0}", matches.Count);
}
方法 Matched 通过比较入参字符串和正则表达式,找到所有符合的结果,并将结果作为 MatchCollect ion 传出来。这样,只要简单的遍历这个 collection ,就可以很快的获得所有的结果。
组的概念
当你获得这样的一个字符串 ” 最后比分是: 19/24” ,你肯定希望有一个正则表达式,他不单能够找到形如 data1/data2 的字符串,还应该能够直接把 data1,data2 作为单独的结果传送出来。否则你需要再对形如 ”19/24” 的字符串进行分析,才能够顺利得到双方的比分。显然,正则表达式不会忽略这个问题,所以他增加了组的概念。你可以把一次搜索的结果分别放入不同的组中,并通过组名或者组的所以分别取得这些组的结果。比如上例,我们就可以用 @”(\d+)/(\d+)” 作为表达式。来看看结果吧:
Regex regex = new Regex(@"(\d+)/(\d+)");
MatchCollection matches = regex.Matches(@" 最后比分是: 19/24 ");
//show matches
Console.WriteLine("////////////////----------------------------------////////////////");
foreach (Match m in matches)
{
//Console.WriteLine("match string is: "{0}", length: {1}", // m.Value.ToString(), m.Value.Length);
foreach ( string name in regex.GetGroupNames())
{
Console.WriteLine("\r capture group "{0}" value is:"{1}""
, name, m.Groups[name].Value);
}
}
Console.WriteLine("matched count: {0}", matches.Count);
输出:
////////////////----------------------------------////////////////
capture group "0" value is:"19/24"
capture group "1" value is:"19"
capture group "2" value is:"24"
matched count: 1
现在清楚了吧, Regex 对象把匹配的结果放入组 0 中。同时,匹配的组信息也放入了对应的组中。组的名称在默认的情况下,是从 1 开始依次增加的整数。 0 作为保留名称,专门用于指示匹配的整个字符串。既然有 ” 默认情况 ” 这样的概念,自然也就意味着用户可以自定义组的名称。方法很简单,在组的前面加上: ?
1<name> 就可以了。好了,现在把前面的正则表达式修改一下,换成 @”(?<score1>\d+)/(?<score1>\d+)” ,现在再看看结果:
2
3////////////////----------------------------------////////////////
4
5capture group "0" value is:"19/24"
6
7capture group "score1" value is:"19"
8
9capture group "score2" value is:"24"
10
11matched count: 1
12
13换成自己定义的名字了吧,哈哈!为了在今后的测试中,能够更加方便的看到所有结果,我们对前面介绍过的 showMatches() 做一点小小的调整。这样,如果在表达式中包含了组的定义,我们也可以在不需要修改任何代码的情况下,直接看到所有的组信息了,调整后的方法 showMatchesPro() 如下:
14
15public static void showMatchesPro( string expression, RegexOptions option, string ms)
16
17{
18
19Regex regex = new Regex(exp ression, option);
20
21MatchCollection matches = regex.Matches(ms);
22
23//show matches
24
25Console.WriteLine("////////////////----------------------------------////////////////");
26
27Console.WriteLine(" string: \"{0}\"\r\n expression: \"{1}\"\r\n match result is:",
28
29ms, expression);
30
31foreach (Match m in matches)
32
33{ foreach ( string name in regex.GetGroupNames())
34
35{
36
37Console.WriteLine("\r capture group \"{0}\" value is:\"{1}\"",
38
39&</score1></score1></name>