200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > C#中利用正则表达式实现字符串搜索

C#中利用正则表达式实现字符串搜索

时间:2024-03-06 04:51:24

相关推荐

C#中利用正则表达式实现字符串搜索

get新技能是需要付出行动的,即使看得再多也还是要动手试一试。今天小编跟大家分享的是C#中利用正则表达式实现字符串搜索,一起来学习了解下吧!

1、正则表达式简介

正则表达式提供了功能强大、灵活而又高效的方法来处理文本。正则表达式的全面模式匹配表示法可以快速地分析大量的文本以找到特定的字符模式;提取、编辑、替换或删除文本子字符串;或将提取的字符串添加到集合以生成报告。对于处理字符串(例如 HTML 处理、日志文件分析和 HTTP 标头分析)的许多应用程序而言,正则表达式是不可缺少的工具。

.NET 框架正则表达式并入了其他正则表达式实现的最常见功能,被设计为与Perl5 正则表达式兼容,.NET 框架正则表达式还包括一些在其他实现中尚未提供的功能,.NET 框架正则表达式类是基类库的一部分,并且可以和面向公共语言运行库的任何语言或工具一起使用。

2、字符串搜索

正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。正是元字符组为正则表达式提供了处理能力。当前,所有的文本编辑器都有一些搜索功能,通常可以打开一个对话框,在其中的一个文本框中键入要定位的字符串,如果还要同时进行替换操作,可以键入一个替换字符串,比如在Windows操作系统中的记事本、Office系列中的文档编辑器都有这种功能。这种搜索最简单的方式,这类问题很容易用String类的()方法来解决,但如果需要在文档中识别某个重复的,该怎么办?编写一个例程,从一个类中选择重复的字是比较复杂的,此时使用语言就很适合。

一般表达式语言是一种可以编写搜索表达式的语言。在该语言中,可以把文档中要搜索的文本、转义序列和特定含义的其他字符组合在一起,例如序列b表示一个字的开头和结尾(子的边界),如果要表示正在查找的以字符th开头的字,就可以编写一般表达式bth(即序列字符界是-t-h)。如果要搜索所有以th结尾的字,就可以编写thb(序列t-h-字边界)。但是,一般表达式要比这复杂得多,例如,可以在搜索操作中找到存储部分文本的工具性程序(facility)。

3、.NET 框架的正则表达式类

下面通过介绍 .NET 框架的正则表达式类,熟悉一下.NET框架下的正则表达式的使用方法。

3.1 Regex 类表示只读正则表达式

Regex 类包含各种静态方法,允许在不显式实例化其他类的对象的情况下使用其他正则表达式类。以下代码示例创建了 Regex 类的实例并在初始化对象时定义一个简单的正则表达式。请注意,使用了附加的反斜杠作为转义字符,它将 s 匹配字符类中的反斜杠指定为原义字符。

Regex r; // 声明一个 Regex类的变量r = new Regex("\s2000"); // 定义表达式

3.2 Match 类表示正则表达式匹配操作的结果

以下示例使用 Regex 类的 Match 方法返回 Match 类型的对象,以便找到输入字符串中第一个匹配。此示例使用 Match 类的 属性来指示是否已找到匹配。

Regex r = new Regex("abc"); // 定义一个Regex对象实例Match m = r.Match("123abc456"); // 在字符串中匹配if (m.Success){Console.WriteLine("Found match at position " + m.Index); //输入匹配字符的位置}

3.3 MatchCollection 类表示非重叠匹配的序列

该集合为只读的,并且没有公共构造函数。MatchCollection 的实例是由 Regex.Matches 属性返回的。使用 Regex 类的 Matches 方法,通过在输入字符串中找到的所有匹配填充 MatchCollection。下面代码示例演示了如何将集合复制到一个字符串数组(保留每一匹配)和一个整数数组(指示每一匹配的位置)中。

MatchCollection mc;String[] results = new String[20];int[] matchposition = new int[20];Regex r = new Regex("abc"); //定义一个Regex对象实例mc = r.Matches("123abc4abcd");for (int i = 0; i mc.Count; i++) //在输入字符串中找到所有匹配{results[i] = mc[i].Value; //将匹配的字符串添在字符串数组中matchposition[i] = mc[i].Index; //记录匹配字符的位置}

3.4 GroupCollection 类表示捕获的组的集合

该集合为只读的,并且没有公共构造函数。GroupCollection 的实例在 Match.Groups 属性返回的集合中返回。下面的控制台应用程序查找并输出由正则表达式捕获的组的数目。

using System;using System.Text.RegularExpressions;public class RegexTest{public static void RunTest(){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();}}

该示例产生下面的输出:

Number of groups found = 3

3.5 CaptureCollection 类表示捕获的子字符串的序列

由于限定符,捕获组可以在单个匹配中捕获多个字符串。Captures属性(CaptureCollection 类的对象)是作为 Match 和 group 类的成员提供的,以便于对捕获的子字符串的集合的访问。例如,如果使用正则表达式 ((a(b))c)+(其中 + 限定符指定一个或多个匹配)从字符串"abcabcabc"中捕获匹配,则子字符串的每一匹配的 Group 的 CaptureCollection 将包含三个成员。

下面的程序使用正则表达式 (Abc)+来查找字符串"XYZAbcAbcAbcXYZAbcAb"中的一个或多个匹配,阐释了使用 Captures 属性来返回多组捕获的子字符串。

using System;using System.Text.RegularExpressions;public class RegexTest{public static void RunTest(){int counter;Match m;CaptureCollection cc;GroupCollection gc;Regex r = new Regex("(Abc)+"); //查找"Abc"m = r.Match("XYZAbcAbcAbcXYZAbcAb"); //设定要查找的字符串gc = m.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;Console.WriteLine("Captures count = " + counter.ToString());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();}}

此例返回下面的输出结果:

Captured groups = 2Captures count = 1AbcAbcAbc Starts at character 3Captures count = 3Abc Starts at character 3Abc Starts at character 6Abc Starts at character 9

3.6 Capture 类包含来自单个子表达式捕获的结果

在 Group 集合中循环,从 Group 的每一成员中提取 Capture 集合,并且将变量 posn 和 length 分别分配给找到每一字符串的初始字符串中的字符位置,以及每一字符串的长度。

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++){cc = m.Groups[i].Captures;for (int j = 0; j cc.Count; j++){posn = cc[j].Index; //捕获对象位置length = cc[j].Length; //捕获对象长度}}

图1:对象关系

把组合字符组合起来后,每次都会返回一个组对象,就可能并不是我们希望的结果。如果希望把组合字符作为搜索模式的一部分,就会有相当大的系统开销。对于单个的组,可以用以字符序列"?:"开头的组禁止这么做,就像URI样例那样。而对于所有的组,可以在RegEx.Matches()方法上指定RegExOptions.ExplicitCapture标志。

4、利用正则表达式实现字符串搜索

4.1 在C#中使用.NET一般表达式引擎

下面将通过一个样例的开发,执行并显示一些搜索的结果,说明一般表达式的一些特性,以及如何在C#中使用.NET一般表达式引擎。说明使用[email protected]

String Text=@"I can not find my position in Beijing";

把这个文本称为输入字符串,为了说明一般表达式.NET类,本文先进行一次纯文本的搜索,这次搜索不带任何转义序列或一般表达式命令。假定要查找所有字符串ion,把这个搜索字符串称为模式。使用一般表达式和上面声明的变量Text,编写出下面的代码:

String Pattern = "ion";MatchCollection Matches = Regex.Matches(Text,Pattern,RegexOptions);foreach(Match NextMatch in Matches){ Console.WriteLine(NextMatch.Index); }

在这段代码中,使用了System.Text.RegularExpressions名称空间中Regex类的静态方法Match()。这个方法的参数是一些输入文本、一个模式和RegexOptions每句中的一组可选标志。Matches()返回MatchCollection,每个匹配都用一个Match对象来表示。在上面的代码中,只是在集合中迭代,使用Match类的Index属性,返回输入文本中匹配所在的索引。运行这段代码,将得到1个匹配项。

一般集合的功能主要取决于模式字符串。原因是模式字符串不仅仅包含纯文本。如前所述。还包含元字符和转义序列,元字符是给出命令的特殊字符,而转义序列的工作方式与C#的转义序列相同,它们都是以反斜杠开头的字符,具有特殊的含义。例如,假定要查找以n开头的字,就可以使用转义序列b,它表示一个字的边界(字的边界是以某个字母数字标的字符开头,或者后面是一个空白字符或标点符号),下面编写如下代码:

String Pattern = @"bn";MatchCollection Matches = Regex.Matches(Text,Pattern,RegexOptions.IgnoreCase|RegexOptions.ExplicitCapture);

要在运行时把b传递给.NET一般表达式引擎,反斜杠不应被C#编译器解释为转义序列。如果要查找以序列ion结尾的字,可以使用下面的代码:

String Pattern = @"ionb";

如果要查找以字母n开头,以序列ion结尾的所有字,需要一个以bn开头,以ionb结尾的模式,中间内容怎么办?需要告诉计算机n和ion中间的内容可以是任意长度的字符,只要字符不是空白即可,正确的模式如下所示:

String Pattern = @"bnS*ionb";

4.2 特定字符或转义序列

大多数重要的正则表达式语言运算符都是非转义的单个字符。转义符 (单个反斜杠)通知正则表达式分析器反斜杠后面的字符不是运算符。例如,分析器将星号 (*) 视为重复限定符,而将后跟星号的反斜杠 (*) 视为 Unicode 字符 002A。

使用一般表达式要习惯的一点是,查看像这样怪异的字符序列,但这个序列的工作是非常逻辑化的。转义序列S表示任何不适空白的字符。*称为数量词,其含义是前面的字符可以重复任意次,包括0次。序列S*表示任何不适空白的字符。因此,上面的模式匹配于以n开头,以ion结尾的任何单个字。下表中列出的字符转义在正则表达式和替换模式中都会被识别。

表1:特定字符或转义序列

特定字符或转义序列含义样例 匹配的样例^ 输入文本的开头^B B,但只能是文本中的第一个字符$ 输入文本的结尾X$X,但只能是文本中的最后一个字符. 除了换行字符(n)以外的所有单个字符i.ationisation、ization* 可以重复0次或多次的前导字符ra*trat、raat等+ 可以重复1次或多次的前导字符ra+trt、rat、raat等?可以重复0次或1次的前导字符ra?t 只有rt和rat匹配s 任何空白字符 sa [space]a,ta,na(t和n与C#的t和n含义相同)S 任何不是空白的字符SFaF,rF,cF,但不能是tfb 字边界ionb以ion结尾的任何字B 不是字边界的位置 BXB 字中间的任何X

如果要搜索一个元字符,也可以通过带有反斜杠的转义字符来表示。例如,.表示除了换行字符以外的任何字符,而.表示一个点。

可以把可替换的字符放在方括号中,请求匹配包含这些字符。例如,[1|c]表示字符可以是1或者是c。如果要搜索map或者man,可以使用序列"ma[n|p]"(仅指引号内字符,下面雷同)。在方括号中,也可以制定一个范围,例如"[a-z]"表示所有的小写字母(使用连字号 (-) 允许指定连续字符范围),"[B-F]"表示B到F之间的所有大写字母,"[0-9]"表示一个数字,如果要搜索一个整数(该序列只包含0到9的字符),就可以编写"[0-9]+"(注意,使用+字符表示至少要有这样一个数字,但可以有多个数字,所以9、83和3443等都是匹配的。)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。