正则表达式查询

1 在C#中使用.NET通常表达式引擎

  下面将经过一个样例的开发,执行并显示一些搜索的结果,说明通常表达式的一些特性,以及如何在C#中使用.NET通常表达式引擎。说明使用字符串时应在前面加上符号@。html

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结尾的字,可使用下面的代码:spa

String Pattern = @"ion\b";

若是要查找以字母n开头,以序列ion结尾的全部字,须要一个以\bn开头,以ion\b结尾的模式,中间内容怎么办?须要告诉计算机n和ion中间的内容能够是任意长度的字符,只要字符不是空白便可,正确的模式以下所示:code

String Pattern = @"\bn\S*ion\b";

 

2  特定字符或转义序列
  大多数重要的正则表达式语言运算符都是非转义的单个字符。转义符 \(单个反斜杠)通知正则表达式分析器反斜杠后面的字符不是运算符。例如,分析器将星号 (*) 视为重复限定符,而将后跟星号的反斜杠 (\*) 视为 Unicode 字符 002A。
  使用通常表达式要习惯的一点是,查看像这样怪异的字符序列,但这个序列的工做是很是逻辑化的。转义序列\S表示任何不适空白的字符。*称为数量词,其含义是前面的字符能够重复任意次,包括0次。序列\S*表示任何不适空白的字符。所以,上面的模式匹配于以n开头,以ion结尾的任何单个字。下表中列出的字符转义在正则表达式和替换模式中都会被识别。
  表1:特定字符或转义序列htm

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

  若是要搜索一个元字符,也能够经过带有反斜杠的转义字符来表示。例如,.表示除了换行字符之外的任何字符,而\.表示一个点。 能够把可替换的字符放在方括号中,请求匹配包含这些字符。例如,[1|c]表示字符能够是1或者是c。若是要搜索map或者man,可使用序列"ma[n|p]"(仅指引号内字符,下面雷同)。在方括号中,也能够制定一个范围,例如"[a-z]"表示全部的小写字母(使用连字号 (-) 容许指定连续字符范围),"[B-F]"表示B到F之间的全部大写字母,"[0-9]"表示一个数字,若是要搜索一个整数(该序列只包含0到9的字符),就能够编写"[0-9]+"(注意,使用+字符表示至少要有这样一个数字,但能够有多个数字,因此九、83和3443等都是匹配的。) 下面看看通常表达式的结果,编写一个实例RegularExpressionsZzy。创建几个通常表达式,显示其结果,让用户了解一下表达式是如何工做的。
  该实例的核心是一个方法WriteMatches(),它把MatchCollection中的全部匹配以比较详细的方式显示出来。对于每一个匹配,它都会显示该匹配在输入字符串中所在的索引,匹配的字符串和一个略长的字符串,其中包含输入文本中至多8个外围字符,其中至少有5个字符放在匹配的前面,至多5个字符放在匹配的后面(若是匹配的位置在输入文本的开头或结尾5个字符内,则结果中匹配先后的字符就会少于4个)。换言之,靠近输入文本末尾的匹配应是"and messaging ofd",匹配的先后各有5个字符,但位于输入文本的最后一个字上的匹配就应是"g of data",匹配的字后只有一个字符。由于在该字符的后面是字符串的结尾。这个长字符串能够更清楚地代表通常表达式是在什么地方查找到匹配的:对象

static void WriteMatches(string text, MatchCollection matches)
{
 Console.WriteLine("Original text was: \n\n" + text + "\n");
 Console.WriteLine("No. of matches: " + matches.Count);
 foreach (Match nextMatch in matches)
 {
  int Index = nextMatch.Index;
  string result = nextMatch.ToString();
  int charsBefore = (Index < 5) ? Index : 5;
  int fromEnd = text.Length - Index - result.Length;
  int charsAfter = (fromEnd < 5) ? fromEnd : 5;
  int charsToDisplay = charsBefore + charsAfter + result.Length;
  Console.WriteLine("Index: {0}, \tString: {1}, \t{2}",Index, result, 
  text.Substring(Index - charsBefore, charsToDisplay));
 }
}

在这个方法中,处理过程是肯定在较长的字符串中有多少个字符能够显示,而无需超限输入文本的开头或结尾。注意在Match对象上使用了另外一个属性Value,它包含标识该匹配的字符串,并且,RegularExpressionsZzy只包含名为Find_po,Find_n等的方法,这些方法根据本文执行某些搜索操做。
  blog

3 正则表达式选项
  可使用影响匹配行为的选项修改正则表达式模式。能够经过两种基本方法设置正则表达式选项:其一是能够在 Regex(pattern, options) 构造函数中的 options 参数中指定,其中 options 是 RegexOptions 枚举值的按位"或"组合;其二是使用内联 (?imnsx-imnsx:) 分组构造或 (?imnsx-imnsx) 其余构造在正则表达式模式内设置它们。
  在内联选项构造中,一个选项或一组选项前面的减号 (-) 用于关闭这些选项。例如,内联构造 (?ix-ms) 将打开 IgnoreCase 和 IgnorePatternWhiteSpace 选项而关闭 Multiline 和 Singleline 选项。
  表2:RegexOptions 枚举的成员以及等效的内联选项字符索引

RegexOption 成员 内联字符 说明
None 指定不设置任何选项。
IgnoreCase i 指定不区分大小写的匹配。
Multiline m 指定多行模式。更改 ^ 和 $ 的含义,以使它们分别与任何行的开头和结尾匹配,而不仅是与整个字符串的开头和结尾匹配。
ExplicitCapture n 指定惟一有效的捕获是显式命名或编号的 (?<name>...) 形式的组。这容许圆括号充当非捕获组,从而避免了由 (?:...) 致使的语法上的笨拙。
Compiled 指定正则表达式将被编译为程序集。生成该正则表达式的 Microsoft 中间语言 (MSIL) 代码;以较长的启动时间为代价,获得更快的执行速度。
Singleline s 指定单行模式。更改句点字符 (.) 的含义,以使它与每一个字符(而不是除 \n 外的全部字符)匹配。
IgnorePatternWhitespace x 指定从模式中排除非转义空白并启用数字符号 (#) 后面的注释。请注意,空白永远不会从字符类中消除。
RightToLeft 指定搜索是从右向左而不是从左向右进行的。具备此选项的正则表达式将移动到起始位置的左边而不是右边。(所以,起始位置应指定为字符串的结尾而不是开头。)为了不构造具备无限循环的正则表达式的可能性,此选项不能在中流指定。可是,(?<) 回顾后发构造提供了可用做子表达式的相似替代物。
ECMAScript 指定已为表达式启用了符合 ECMAScript 的行为。此选项仅可与 IgnoreCase 和 Multiline 标志一块儿使用。将 ECMAScript 同任何其余标志一块儿使用将致使异常。