1. 程式人生 > >正則表示式match和group的區別 具有相同模式的字串使用組的提取案例及原理

正則表示式match和group的區別 具有相同模式的字串使用組的提取案例及原理

一、案例:

Match類

示例:查找出字串中包含的url

string text = "FirstUrl: http://www.sohu.com ,SecondUrl: http://www.baidu.com ";
string pattern = @"\b(\S+)://(\S+)\b"; //匹配URL的模式
MatchCollection mc = Regex.Matches(text, pattern); //滿足pattern的匹配集合
Console.WriteLine("文字中包含的URL地址有:");
foreach (Match match in mc)
{
  Console.WriteLine(match.Value

);
}
Console.ReadLine();

結果:

 Group類

示例:找到字串中包含的url,並找出每個url的協議和域名地址

string text = "FirstUrl: http://www.sohu.com ,SecondUrl: http://www.baidu.com ";
string pattern = @"\b(?<protocol>\S+)://(?<address>\S+)\b"; //匹配URL的模式,並分組
MatchCollection mc = Regex.Matches(text, pattern); //滿足pattern的匹配集合

Console.WriteLine("文字中包含的URL地址有:");
foreach (Match match in mc)
{
  GroupCollection gc = match.Groups;
  string outputText = "URL:" + match.Value + ";Protocol:" + gc["protocol"].Value + ";Address:" + gc["address"].Value;
  Console.WriteLine(outputText); 
}

Console.Read();

說明:"?<protocol>

"和"?<address>"定義了每個組的別名protocol和address

(注意:這是一個match內的設定不同名稱的組,對這些組進行提取)


二、原理 

正則表示式模式可以包含子表示式,這些子表示式是通過將正則表示式模式的一部分用括號括起來定義的每個這樣的子表示式構成一個組

Groups 屬性提供對有關這些子表示式匹配的資訊

例如,與北美電話號碼匹配的正則表示式模式(\d{3})-(\d{3}-\d{4}) 有兩個子表示式。

第一組由區號構成,它包含電話號碼的前三位數字。此組由正則表示式的第一部分(\d{3}) 捕獲。

第二組由單個電話號碼組成,它包含電話號碼的後七位數字。此組由正則表示式的第二部分(\d{3}-\d{4}) 捕獲。

然後,可以從由Groups 屬性返回的 物件來檢索這兩個組,如以下示例所示。

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(\d{3})-(\d{3}-\d{4})";
      string input = "212-555-6666 906-932-1111 415-222-3333 425-888-9999";
      MatchCollection matches = Regex.Matches(input, pattern);

      foreach (Match match in matches)
      {
         Console.WriteLine("Area Code:        {0}", match.Groups[1].Value);//字串內第一個匹配match的第一個組(\d{3})
         Console.WriteLine("Telephone number: {0}", match.Groups[2].Value);
         Console.WriteLine();
      }
      Console.WriteLine();
   }
}
// The example displays the following output:
//       Area Code:        212
//       Telephone number: 555-6666
//       
//       Area Code:        906
//       Telephone number: 932-1111
//       
//       Area Code:        415
//       Telephone number: 222-3333
//       
//       Area Code:        425
//       Telephone number: 888-9999


Match.Groups 屬性返回的 物件始終至少具有一個成員

如果正則表示式引擎在特定的輸入字串中找不到任何匹配項,則集合中的單個Group 物件的 屬性將設定為false,且 Group 物件的Value 屬性將設定為。

如果正則表示式引擎可以找到匹配項Groups 屬性返回的 物件的第一個元素將包含一個與整個正則表示式模式匹配的字串

如果正則表示式包含捕獲組,則每個後續元素都表示一個被捕獲組。有關詳細資訊,請參閱“分組構造和正則表示式物件”來區分這篇 文章。

下面的示例嘗試將正則表示式模式與示例字串進行匹配。此示例將Groups 屬性用於儲存要在控制檯上顯示的匹配項所檢索的資訊。

using System;
using System.Text.RegularExpressions;

class Example 
{
   static void Main() 
   {
      string text = "One car red car blue car";
      string pat = @"(\w+)\s+(car)";

      // Instantiate the regular expression object.
      Regex r = new Regex(pat, RegexOptions.IgnoreCase);

      // Match the regular expression pattern against a text string.
      Match m = r.Match(text);
      int matchCount = 0;
      while (m.Success) 
      {
         Console.WriteLine("Match"+ (++matchCount));
         for (int i = 1; i <= 2; i++) 
         {
            Group g = m.Groups[i];
            Console.WriteLine("Group"+i+"='" + g + "'");
            CaptureCollection cc = g.Captures;
            for (int j = 0; j < cc.Count; j++) 
            {
               Capture c = cc[j];
               System.Console.WriteLine("Capture"+j+"='" + c + "', Position="+c.Index);
            }
         }
         m = m.NextMatch();
      }
   }
}
// This example displays the following output:
//       Match1
//       Group1='One'
//       Capture0='One', Position=0
//       Group2='car'
//       Capture0='car', Position=4
//       Match2
//       Group1='red'
//       Capture0='red', Position=8
//       Group2='car'
//       Capture0='car', Position=12
//       Match3
//       Group1='blue'
//       Capture0='blue', Position=16
//       Group2='car'
//       Capture0='car', Position=21

 三、分組構造和正則表示式物件

由正則表示式捕獲組匹配的子字串由 System.Text.RegularExpressions.Group 物件表示,其從 System.Text.RegularExpressions.GroupCollection 物件檢索,其由 Match.Groups 屬性返回。填充 GroupCollection 物件,如下所示:
集合中的第一個 Group 物件(位於索引零的物件)表示整個匹配

•下一組 Group 物件表示未命名(編號)的捕獲組。它們以在正則表示式中定義的順序出現,從左至右。這些組的索引值範圍從 1 到集合中未命名捕獲組的數目。(特定組索引等效於其帶編號的反向引用。有關向後引用的更多資訊,請參見正則表示式中的反向引用構造。)

•最後的 Group 物件組表示命名的捕獲組。它們以在正則表示式中定義的順序出現,從左至右。第一個名為捕獲組的索引值是一個大於最後一個未命名的捕獲組的索引。如果正則表示式中沒有未命名捕獲組,則第一個命名的捕獲組的索引值為零。


如果將限定符應用於捕獲組則對應的 Group 物件的 Capture.Value、 Capture.Index 和 Capture.Length 屬性反映捕獲組捕獲的最後一個子字串。可以檢索一整組子字串,其是按組捕獲的並具有來自 CaptureCollection 物件的限定符,其由 Group.Captures 屬性返回

下面的示例闡釋 Group 和 Capture 物件之間的關係。

using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"(\b(\w+)\W+)+";
      string input = "This is a short sentence.";
      Match match = Regex.Match(input, pattern);
      Console.WriteLine("Match: '{0}'", match.Value);
      for (int <span style="color:#ff0000;">ctr = 1</span>; ctr < match.Groups.Count; ctr++)
      {
         Console.WriteLine("   Group {0}: '{1}'", ctr, match.Groups[ctr].Value);//<span style="color:#ff0000;">ctr = 1開始match內部陣列檢索</span>
         int capCtr = 0;
         foreach (Capture capture in match.Groups[ctr].Captures)//<span style="color:#ff0000;">ctr = 0開始</span>
         {
            Console.WriteLine("      Capture {0}: '{1}'", capCtr, capture.Value);
            capCtr++;
         }
      }
   }
}
// The example displays the following output:
//       Match: 'This is a short sentence. '
//          Group 1: 'sentence.'
//             Capture 0: 'This '
//             Capture 1: 'is '
//             Capture 2: 'a '
//             Capture 3: 'short '
//             Capture 4: 'sentence.'
//          Group 2: 'sentence'
//             Capture 0: 'This'
//             Capture 1: 'is'
//             Capture 2: 'a'
//             Capture 3: 'short'
//             Capture 4: 'sentence'