您可能比较熟悉在 DOS 文件系统中使用的 ? 和 * 元字符,这两个元字符分别代表任意单个字符和字符组。DOS 文件命令 COPY *.DOC A: 命令文件系统将文件扩展名为 .DOC 的所有文件均复制到 A 驱动器的磁盘中。元字符 * 代表文件扩展名 .DOC 前的任何文件名。正则表达式极大地拓展了此基本思路,提供大量的元字符组,使通过相对少的字符描述非常复杂的文本匹配表达式成为可能。
例如,正则表达式 \s2000 在应用到文本正文时,将匹配在字符串“2000”前为任意空白字符(例如空格或制表符)的所有匹配项。
正则表达式还可以执行更复杂的搜索。例如,使用命名组和进行反向参照(在下面各节中说明)的正则表达式 (?<char>\w)\k<char> 搜索相邻的成对字符。当该正则表达式应用到字符串“I'll have a double tall latte”时,它将在单词“I'll”、“tall”和“latte”中找到匹配。(有关此正则表达式的详细信息,请参阅反向参照。)
正则表达式有关的类
Regex
Regex 类表示不可变(只读)正则表达式类。它还包含各种静态方法,允许在不显式实例化其他类的对象的情况下使用其他正则表达式类。
以下代码示例创建了 Regex 类的实例并在初始化对象时定义一个简单的正则表达式。请注意,使用了附加的反斜杠作为转义字符,它将 \s 匹配字符类中的反斜杠指定为原义字符。
[C#]
// Declare object variable of type Regex.
Regex r;
// Instantiate a Regex object and define its regular expression.
r = new Regex("\\s2000");
Match
Match 类表示正则表达式匹配操作的结果。以下示例使用 Regex 类的 Match 方法返回 Match 类型的对象,以便找到输入字符串中第一个匹配。此示例使用 Match 类的 Match.Success 属性来指示是否已找到匹配。
[C#]
// Instantiate a new Regex object.
Regex r = new Regex("abc");
// Find a single match in the string.
Match m = r.Match("123abc456");
if (m.Success)
{
// Print out the character position where a match was found.
// (Character position 3 in this case).
Console.WriteLine("Found match at position " + m.Index);
}
MatchCollection
MatchCollection 类表示成功的非重叠匹配的序列。该集合为不可变(只读)的,并且没有公共构造函数。MatchCollection 的实例是由 Regex.Matches 属性返回的。
以下示例使用 Regex 类的 Matches 方法,通过在输入字符串中找到的所有匹配填充 MatchCollection。以下代码示例将集合复制到一个字符串数组(保留每一匹配)和一个整数数组(指示每一匹配的位置)中。
[C#]
MatchCollection mc;
String[] results = new String[20];
int[] matchposition = new int[20];
// Instantiate a new Regex object and define the regular expression.
Regex r = new Regex("abc");
// Use the Matches method to find all matches in the input string.
mc = r.Matches("123abc4abcd");
// Loop through the match collection to retrieve all
// matches and positions.
for (int i = 0; i < mc.Count; i++)
{
// Add the match string to the string array.
results[i] = mc[i].Value;
// Record the character position where the match was found.
matchposition[i] = mc[i].Index;
}
GroupCollection
GroupCollection 类表示捕获的组的集合并返回单个匹配中捕获的组的集合。该集合为不可变(只读)的,并且没有公共构造函数。GroupCollection 的实例在 Match.Groups 属性返回的集合中返回。
以下控制台应用程序示例查找并输出由正则表达式捕获的组的数目。有关如何提取组集合的每一成员中的单独捕获的示例,请参阅下面一节的 CaptureCollection 示例。
[C#]
using System;
using System.Text.RegularExpressions;
public class RegexTest
{
public static void RunTest()
{
// Define groups "abc", "ab", and "b".
Regex r = new Regex("(a(b))c");
Match m = r.Match("abdabc");
Console.WriteLine("Number of groups found = " + m.Groups.Count);
}
public static void Main()
{
RunTest();
}
}
该示例产生下面的输出。
[C#]
Number of groups found = 3
CaptureCollection
CaptureCollection 类表示捕获的子字符串的序列,并且返回由单个捕获组执行的捕获的集合。由于限定符,捕获组可以在单个匹配中捕获多个字符串。Captures 属性(CaptureCollection 类的对象)是作为 Match 和 group 类的成员提供的,以便于对捕获的子字符串的集合的访问。
例如,如果使用正则表达式 ((a(b))c)+(其中 + 限定符指定一个或多个匹配)从字符串“abcabcabc”中捕获匹配,则子字符串的每一匹配的 Group 的 CaptureCollection 将包含三个成员。
以下控制台应用程序示例使用正则表达式 (Abc)+ 来查找字符串“XYZAbcAbcAbcXYZAbcAb”中的一个或多个匹配。该示例阐释了使用 Captures 属性来返回多组捕获的子字符串。
[C#]
using System;
using System.Text.RegularExpressions;
public class RegexTest
{
public static void RunTest()
{
int counter;
Match m;
CaptureCollection cc;
GroupCollection gc;
// Look for groupings of "Abc".
Regex r = new Regex("(Abc)+");
// Define the string to search.
m = r.Match("XYZAbcAbcAbcXYZAbcAb");
gc = m.Groups;
// Print the number of groups.
Console.WriteLine("Captured groups = " + gc.Count.ToString());
// Loop through each group.
for (int i=0; i < gc.Count; i++)
{
cc = gc[i].Captures;
counter = cc.Count;
// Print number of captures in this group.
Console.WriteLine("Captures count = " + counter.ToString());
// Loop through each capture in group.
for (int ii = 0; ii < counter; ii++)
{
// Print capture and position.
Console.WriteLine(cc[ii] + " Starts at character " +
cc[ii].Index);
}
}
}
public static void Main() {
RunTest();
}
}
此示例返回下面的输出结果。
[C#]
Captured groups = 2
Captures count = 1
AbcAbcAbc Starts at character 3
Captures count = 3
Abc Starts at character 3
Abc Starts at character 6
Abc Starts at character 9
Group
group 类表示来自单个捕获组的结果。因为 Group 可以在单个匹配中捕获零个、一个或更多的字符串(使用限定符),所以它包含 Capture 对象的集合。因为 Group 继承自 Capture,所以可以直接访问最后捕获的子字符串(Group 实例本身等价于 Captures 属性返回的集合的最后一项)。
Group 的实例是由 Match.Groups(groupnum) 属性返回的,或者在使用“(?<groupname>)”分组构造的情况下,是由 Match.Groups("groupname") 属性返回的。
以下代码示例使用嵌套的分组构造来将子字符串捕获到组中。
[C#]
int[] matchposition = new int[20];
String[] results = new String[20];
// Define substrings abc, ab, b.
Regex r = new Regex("(a(b))c");
Match m = r.Match("abdabc");
for (int i = 0; m.Groups[i].Value != ""; i++)
{
// Copy groups to string array.
results[i]=m.Groups[i].Value;
// Record character position.
matchposition[i] = m.Groups[i].Index;
}
此示例返回下面的输出结果。
[C#]
results[0] = "abc" matchposition[0] = 3
results[1] = "ab" matchposition[1] = 3
results[2] = "b" matchposition[2] = 4
以下代码示例使用命名的分组构造从包含“DATANAME:VALUE”格式(正则表达式通过冒号“:”拆分)的数据的字符串捕获子字符串。
[C#]
Regex r = new Regex("^(?<name>\\w+):(?<value>\\w+)");
Match m = r.Match("Section1:119900");
此正则表达式返回下面的输出结果。
[C#]
m.Groups["name"].Value = "Section1"
m.Groups["value"].Value = "119900"
Capture
Capture 类包含来自单个子表达式捕获的结果。
以下示例在 Group 集合中循环,从 Group 的每一成员中提取 Capture 集合,并且将变量 posn 和 length 分别分配给找到每一字符串的初始字符串中的字符位置,以及每一字符串的长度。
[C#]
Regex r;
Match m;
CaptureCollection cc;
int posn, length;
r = new Regex("(abc)*");
m = r.Match("bcabcabc");
for (int i=0; m.Groups[i].Value != ""; i++)
{
// Capture the Collection for Group(i).
cc = m.Groups[i].Captures;
for (int j = 0; j < cc.Count; j++)
{
// Position of Capture object.
posn = cc[j].Index;
// Length of Capture object.
length = cc[j].Length;
}
}