正则表达式

字符类 

[ character_group ] 匹配 character_group中的任何单个字符。 默认情况下,匹配区分大小写。 [ae] "gray" 中的 "a"

"lane" 中的 "a" 和 "e"
[^ character_group ] 求反:与不在 character_group 中的任意单个字符匹配。 默认情况下, character_group 中的字符区分大小写。 [^aei] "reign" 中的 "r""g" 和 "n"
[ first - last ] 字符范围:与从 first 到 last的范围中的任意单个字符匹配。 [A-Z] "AB123" 中的 "A" 和 "B"
. 通配符:与除 \n 之外的任意单个字符匹配。

若要匹配文本句点字符(. 或 \u002E),你必须在该字符前面加上转义符 (\.)。
a.e "nave" 中的 "ave"

"water" 中的 "ate"
\w 与任何单词字符匹配。 \w "ID A1.3" 中的 "I""D""A""1" 和 "3"
\W 与任何非单词字符匹配。 \W "ID A1.3" 中的 " " 和 "."
\s 与任何空白字符匹配。 \w\s "ID A1.3" 中的 "D "
\S 与任何非空白字符匹配。 \s\S "int __ctr" 中的 " _"
\d 与任何十进制数字匹配。 \d "4 = IV" 中的 "4"
\D 匹配不是十进制数的任意字符。 \D "4 = IV" 中的 " ""="" ""I" 和 "V"

定位点

^ 默认情况下,必须从字符串的开头开始匹配;在多行模式中,必须从该行的开头开始。 ^\d{3} "901-333-" 中的 "901"
$ 默认情况下,匹配必须出现在字符串的末尾,或在字符串末尾的 \n 之前;在多行模式中,必须出现在该行的末尾之前,或在该行末尾的 \n 之前。 -\d{3}$ "-901-333" 中的 "-333"
\A 匹配必须出现在字符串的开头。 \A\d{3} "901-333-" 中的 "901"
\Z 匹配必须出现在字符串的末尾或出现在字符串末尾的 \n 之前。 -\d{3}\Z "-901-333" 中的 "-333"
\z 匹配必须出现在字符串的末尾。 -\d{3}\z "-901-333" 中的 "-333"
\G 匹配必须出现在上一个匹配结束的地方。 \G\(\d\) "(1)(3)(5)[7](9)" 中的 "(1)""(3)" 和 "(5)"
\b 匹配必须出现在 \w (字母数字)和 \W (非字母数字)字符之间的边界上。 \b\w+\s\w+\b "them theme them them" 中的 "them theme" 和 "them them"
\B 匹配不得出现在 \b 边界上。 \Bend\w*\b "end sends endure lender" 中的 "ends" 和 "ender"

数量词

 

* 匹配上一个元素零次或多次。 \d*\.\d ".0""19.9""219.9"
+ 匹配上一个元素一次或多次。 "be+" "been" 中的 "bee""bent" 中的 "be"
? 匹配上一个元素零次或一次。 "rai?n" "ran""rain"
{ n } 匹配上一个元素恰好 n 次。 ",\d{3}" "1,043.6" 中的 ",043""9,876,543,210" 中的 ",876"",543" 和 ",210"
{ n ,} 匹配上一个元素至少 n 次。 "\d{2,}" "166""29""1930"
{ n , m } 匹配上一个元素至少 n 次,但不多于 m 次。 "\d{3,5}" "166""17668"

"193024" 中的 "19302"
*? 匹配上一个元素零次或多次,但次数尽可能少。 \d*?\.\d ".0""19.9""219.9"
+? 匹配上一个元素一次或多次,但次数尽可能少。 "be+?" "been" 中的 "be""bent" 中的 "be"
?? 匹配上一个元素零次或一次,但次数尽可能少。 "rai??n" "ran""rain"
{ n }? 匹配前面的元素恰好 n 次。 ",\d{3}?" "1,043.6" 中的 ",043""9,876,543,210" 中的 ",876"",543" 和 ",210"
{ n ,}? 匹配上一个元素至少 n 次,但次数尽可能少。 "\d{2,}?" "166""29""1930"
{ n , m }? 匹配上一个元素的次数介于 n 和 m 之间,但次数尽可能少。 "\d{3,5}?" "166""17668"

"193024" 中的 "193" 和 "024"

惰性限定符:??*?+?{n,m}? 。 这些构造会指示回溯引擎首先搜索最小数量的重复项。 相反,普通贪婪限定符会尝试首先匹配最大数量的重复项。

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string greedyPattern = @".+(\d+)\.";
      string lazyPattern = @".+?(\d+)\.";
      string input = "This sentence ends with the number 107325.";
      Match match;

      // Match using greedy quantifier .+.
      match = Regex.Match(input, greedyPattern);
      if (match.Success)
         Console.WriteLine("Number at end of sentence (greedy): {0}",
                           match.Groups[1].Value);
      else
         Console.WriteLine("{0} finds no match.", greedyPattern);

      // Match using lazy quantifier .+?.
      match = Regex.Match(input, lazyPattern);
      if (match.Success)
         Console.WriteLine("Number at end of sentence (lazy): {0}",
                           match.Groups[1].Value);
      else
         Console.WriteLine("{0} finds no match.", lazyPattern);
   }
}
// The example displays the following output:
//       Number at end of sentence (greedy): 5
//       Number at end of sentence (lazy): 107325
模式描述
.+(贪婪限定符) 匹配任何字符的至少一个匹配项。 这会导致正则表达式引擎匹配整个字符串,然后根据需要进行回溯以匹配模式的其余部分。本例会尽可能多的匹配,即This sentence ends with the number 10732
.+?(惰性限定符) 匹配任何字符的至少一个匹配项,但匹配尽可能少。本例尽可能少匹配,即This sentence ends with the number 
(\d+) 匹配至少一个数字字符,并将其分配给第一个捕获组。
\. 匹配句点。

 

替换构造

| 匹配以竖线 (|) 字符分隔的任何一个元素。 th(e|is|at) "this is the day." 中的 "the" 和 "this"

 

识别重复单词

using System;
using System.Text.RegularExpressions;

public class Class1
{
   public static void Main()
   {
      string pattern = @"\b(\w+?)\s\1\b";
      string input = "This this is a nice day. What about this? This tastes good. I saw a a dog.";
      foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
         Console.WriteLine("{0} (duplicates '{1}') at position {2}",
                           match.Value, match.Groups[1].Value, match.Index);
   }
}
// The example displays the following output:
//       This this (duplicates 'This') at position 0
//       a a (duplicates 'a') at position 66

正则表达式模式 \b(\w+?)\s\1\b 的解释如下:

表 1
模式解释
\b 在单词边界处开始。
(\w+?) 匹配一个或多个单词字符,但字符要尽可能的少。 它们一起构成可称为 \1 的组。
\s 与空白字符匹配。
\1 与等于名为 \1 的组的子字符串匹配。
\b 与字边界匹配。

静态正则表达式

静态方法调用所使用的模式中的操作代码由正则表达式引擎缓存在内部。默认情况下,将缓存最后 15 个最近使用的静态正则表达式模式。 对于需要大量已缓存的静态正则表达式的应用程序,可通过设置 Regex.CacheSize 属性来调整缓存大小。

正则表达式实例

实例化 Regex 对象是不可变的(只读),它表示一个与单个正则表达式紧密耦合的正则表达式引擎。未对正则表达式进行缓存

鉴于对象实例化和正则表达式编译产生的开销,因此创建并迅速销毁大量 Regex 对象的进程成本非常高。 对于使用大量不同正则表达式的应用,可以调用静态方法 Regex,并尽量增加正则表达式缓存大小,从而优化性能。

 

命名的分组构造

var r = new Regex(@"^(?<name>\w+):(?<value>\w+)");
Match m = r.Match("Section1:119900");
Console.WriteLine(m.Groups["name"].Value);
Console.WriteLine(m.Groups["value"].Value);
// The example displays the following output:
//       Section1
//       119900

 

限定符可以匹配由捕获组定义的模式的多个匹配项。 在此情况下,Value 对象的 Length 和 Group 属性仅包含有关最后捕获的子字符串的信息。 例如,下面的正则表达式匹配以句点结束的单个句子。 此表达式使用两个分组构造:第一个分组构造捕获单个单词和空白字符;第二个分组构造捕获单个单词。 如示例中的输出所示,虽然正则表达式成功捕获整个句子,但第二个捕获组仅捕获了最后一个单词。

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b((\w+)\s?)+\.";
      string input = "This is a sentence. This is another sentence.";
      Match match = Regex.Match(input, pattern);
      if (match.Success)
      {
         Console.WriteLine("Match: " + match.Value);
         Console.WriteLine("Group 2: " + match.Groups[2].Value);
      }
   }
}
// The example displays the following output:
//       Match: This is a sentence.
//       Group 2: sentence

 

只在必要时捕获

当你只使用子表达式来对其应用限定符并且你对捕获的文本不感兴趣时,应禁用组捕获。 例如,(?:subexpression) 语言元素可防止应用此元素的组捕获匹配的子字符串。 

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is one sentence. This is another.";
      string pattern = @"\b(?:\w+[;,]?\s?)+[.?!]";

      foreach (Match match in Regex.Matches(input, pattern)) {
         Console.WriteLine("Match: '{0}' at index {1}.",
                           match.Value, match.Index);
         int grpCtr = 0;
         foreach (Group grp in match.Groups) {
            Console.WriteLine("   Group {0}: '{1}' at index {2}.",
                              grpCtr, grp.Value, grp.Index);
            int capCtr = 0;
            foreach (Capture cap in grp.Captures) {
               Console.WriteLine("      Capture {0}: '{1}' at {2}.",
                                 capCtr, cap.Value, cap.Index);
               capCtr++;
            }
            grpCtr++;
         }
         Console.WriteLine();
      }
   }
}
// The example displays the following output:
//       Match: 'This is one sentence.' at index 0.
//          Group 0: 'This is one sentence.' at index 0.
//             Capture 0: 'This is one sentence.' at 0.
//
//       Match: 'This is another.' at index 22.
//          Group 0: 'This is another.' at index 22.
//             Capture 0: 'This is another.' at 22.

可以通过以下方式之一来禁用捕获:

  • 使用 (?:subexpression) 语言元素。 此元素可防止在它应用的组中捕获匹配的子字符串。 它不在任何嵌套的组中禁用子字符串捕获。

  • 使用 ExplicitCapture 选项。 在正则表达式模式中禁用所有未命名或隐式捕获。 使用此选项时,只能捕获与使用 (?<name>subexpression) 语言元素定义的命名组匹配的子字符串。 可将 ExplicitCapture 标记传递给 options 类构造函数的 Regex 参数或 options 静态匹配方法的 Regex 参数。

 

提取单个匹配项或第一个匹配项

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string input = "This is a a farm that that raises dairy cattle.";
      string pattern = @"\b(\w+)\W+(\1)\b";
      Match match = Regex.Match(input, pattern);
      while (match.Success)
      {
         Console.WriteLine("Duplicate '{0}' found at position {1}.",
                           match.Groups[1].Value, match.Groups[2].Index);
         match = match.NextMatch();
      }
   }
}
// The example displays the following output:
//       Duplicate 'a' found at position 10.
//       Duplicate 'that' found at position 22.

正则表达式模式 \b(\w+)\W+(\1)\b 的含义如下表所示。

提取单个匹配项或第一个匹配项
模式描述
\b 在单词边界处开始匹配。
(\w+) 匹配一个或多个单词字符。 这是第一个捕获组。
\W+ 匹配一个或多个非单词字符。
(\1) 与第一个捕获的字符串匹配。 这是第二个捕获组。
\b 在单词边界处结束匹配。

 

替换模式

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\d+\.\d{2}\b";
      string replacement = "$$$&";
      string input = "Total Cost: 103.64";
      Console.WriteLine(Regex.Replace(input, pattern, replacement));
   }
}
// The example displays the following output:
//       Total Cost: $103.64

替换模式 $$$& 的含义如下表所示。

表 4
模式替换字符串
$$ 美元符号 ($) 字符。
$& 整个匹配的子字符串。

Match.Result 方法对匹配的字符串执行指定的替换操作并返回相应结果。

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b\d+(,\d{3})*\.\d{2}\b";
      string input = "16.32\n194.03\n1,903,672.08";

      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine(match.Result("$$ $&"));
   }
}
// The example displays the following output:
//       $ 16.32
//       $ 194.03
//       $ 1,903,672.08

 

原子组:(?>subexpression)  

此功能允许回溯引擎保证子表达式仅匹配为该子表达式找到的第一个匹配项。原子组可帮助防止与失败匹配关联的性能问题。

string[] inputs = { "aaaaa", "aaaaab" };
      string backtrackingPattern = @"(a+)\w";

// The example displays the following output:
//       Input: aaaaa
//          Pattern: (a+)\w
//             Match: aaaaa
//             Group 1: aaaa
//       Input: aaaaab
//          Pattern: (a+)\w
//             Match: aaaaab
//             Group 1: aaaaa

正则表达式 ((?>a+))\w 会阻止此行为。 因为所有连续“a”字符会在不进行回溯的情况下匹配,所以第一个捕获组包含所有连续“a”字符。 如果“a”字符后面不是至少一个“a”之外的字符,则匹配会失败。

string[] inputs = { "aaaaa", "aaaaab" };
      string nonbacktrackingPattern = @"((?>a+))\w";

// The example displays the following output:
//       Input: aaaaa
//          Pattern: ((?>a+))\w
//             Match failed.
//       Input: aaaaab
//          Pattern: ((?>a+))\w
//             Match: aaaaab
//             Group 1: aaaaa

 

 

System.Web.RegularExpressions 命名空间包含大量正则表达式对象,这些对象实现预定义的正则表达式模式,用于分析 HTML、XML 和 ASP.NET 文档中的字符串。 例如,TagRegex 类标识字符串中的开始标记,CommentRegex 类标识字符串中的 ASP.NET 注释。

 

posted @ 2020-08-09 20:10  yetsen  阅读(176)  评论(0编辑  收藏  举报