Share via


替代建構

替代建構會修改規則運算式,以啟用兩者之一或條件比對。 .NET Framework 支援三個替代建構:

  • 以 | 進行的模式比對

  • 以 (?(運算式)yes|no) 進行的條件式比對

  • 依據有效擷取群組的條件式比對

以 | 進行的模式比對

您可以使用垂直列 (|) 符合一個模式的字元,其中| 會分隔每個模式的字元。

就像正面字元類別,|字元可以用來比對任何一個單一的字元。 下列範例會同使用正字元類別與 either/or 模式比對 |字元,可找到在字串中出現的文字 "gray" 或 "grey"。 在這種情況下, | 會產生更詳細之規則運算式的字元。

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      ' Regular expression using character class.
      Dim pattern1 As String = "\bgr[ae]y\b"
      ' Regular expression using either/or.
      Dim pattern2 As String = "\bgr(a|e)y\b"

      Dim input As String = "The gray wolf blended in among the grey rocks."
      For Each match As Match In Regex.Matches(input, pattern1)
         Console.WriteLine("'{0}' found at position {1}", _
                           match.Value, match.Index)
      Next      
      Console.WriteLine()
      For Each match As Match In Regex.Matches(input, pattern2)
         Console.WriteLine("'{0}' found at position {1}", _
                           match.Value, match.Index)
      Next      
   End Sub
End Module
' The example displays the following output:
'       'gray' found at position 4
'       'grey' found at position 35
'       
'       'gray' found at position 4
'       'grey' found at position 35           
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      // Regular expression using character class.
      string pattern1 = @"\bgr[ae]y\b";
      // Regular expression using either/or.
      string pattern2 = @"\bgr(a|e)y\b";

      string input = "The gray wolf blended in among the grey rocks.";
      foreach (Match match in Regex.Matches(input, pattern1))
         Console.WriteLine("'{0}' found at position {1}", 
                           match.Value, match.Index);
      Console.WriteLine();
      foreach (Match match in Regex.Matches(input, pattern2))
         Console.WriteLine("'{0}' found at position {1}", 
                           match.Value, match.Index);
   }
}
// The example displays the following output:
//       'gray' found at position 4
//       'grey' found at position 35
//       
//       'gray' found at position 4
//       'grey' found at position 35           

使用 的規則運算式| 字元 \bgr(a|e)y\b,會被解譯為如下表所示的值。

模式

描述

\b

從字緣開始。

gr

比對字元 "gr"。

(a|e)

比對 "a" 或 "e"。

y\b

比對在字組界限上的 "y"。

|字元也可以用來與多個字元或子運算式執行兩者之一的比對,這些字元或運算式可以包含字元常值和規則運算式語言項目的任何組合。 (字元類別並不提供這項功能)。下列的範例會使用 |擷取美國或 的字元 社會安全碼 (SSN),也就是 9 位數的數字,具有 ddd-dd-dddd 的格式,或美國 雇主識別碼 (EIN) 是 9 位數的數字,具有 dd-ddddddd 的格式。

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
      Dim input As String = "01-9999999 020-333333 777-88-9999"
      Console.WriteLine("Matches for {0}:", pattern)
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
      Next   
   End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22

規則運算式 \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b 的解譯方式如下表所示。

模式

描述

\b

從字緣開始。

(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})

比對下列其中一項:兩個十進位數字後接連字號再後接七個十進位數字,或是三個十進位數字、連字號、兩個十進位數字、另一個連字號及四個十進位數字。

\d

結束字緣比對。

回到頁首

以運算式進行的條件式比對

這個語言項目會嘗試比對兩個模式的其中一個,取決於它是否可以比對初始模式。 它的語法為:

(?(expression)yes|no)

其中 expression 是要比對的初始模式、yes 是當 expression 符合時要比對的模式,而 no 則是當 expression 不符合時比對的選擇性模式。 規則運算式引擎會將 運算式 視為零寬度判斷提示。也就是說,規則運算式引擎評估 運算式 之後不會在輸入資料流中下移。 因此,這個建構函式等同於下列:

(?(?=expression)yes|no)

其中 (?=運算式) 是零寬度的判斷提示建構 (如需詳細資訊,請參閱群組建構)。因為規則運算式引擎會將 expression 解譯為錨點 (零寬度的判斷提示), expression 必須是零寬度的判斷提示 (如需詳細資訊,請參閱 規則運算式中的錨點),或者是也包含在 yes 中的子運算式。 否則,就無法符合 yes 模式。

注意事項注意事項

如果 expression 是具名或編號的擷取群組,替代建構會被解譯為擷取測試。如需詳細資訊,請參閱下一節 依據有效擷取群組的條件式比對。換句話說,規則運算式引擎不會嘗試比對擷取的子字串,但是會測試群組的存在或缺乏。

下列範例是一種範例變化,出現在使用 | 的 Either/Or 模式比對與 | 區段中。 它使用條件式比對,來判斷字組界限後的前三個字元是否為兩個位數再後接連字號。 如果他們是如此,它就會嘗試比對美國 雇主識別碼 (EIN)。 否則,它就會嘗試比對美國 社會安全號碼 (SSN)。

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b"
      Dim input As String = "01-9999999 020-333333 777-88-9999"
      Console.WriteLine("Matches for {0}:", pattern)
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
      Next   
   End Sub
End Module
' The example displays the following output:
'       Matches for \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22

規則運算式模式 \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b 的解譯方式如下表所示。

模式

描述

\b

從字緣開始。

(?(\d{2}-)

判斷接下來三個字元,是否由兩個數字與後接的連字號組成。

\d{2}-\d{7}

如果上一個模式符合,便會比對兩個數字,後接連字號,再後接七個數字。

\d{3}-\d{2}-\d{4}

如果上一個模式不符合,便會比對三個十進位數字、連字號、兩個十進位數字、另一個連字號,以及四個十進位數字。

\b

比對字緣。

回到頁首

依據有效擷取群組的條件式比對

這個語言項目會嘗試比對兩個模式的其中一個,取決於它是否可以比對指定的擷取群組。 它的語法為:

(?(名稱)是|no)

(?(編號)是|no)

其中 name 是名稱,而 number 是擷取群組的數目,yes 是當 name 或 number 其中一個符合時要比對的運算式,而 no 則是當不符合時比對的選擇性運算式。

如果 name 並未對應到在規則運算式模式中使用的擷取群組名稱,替代建構會解譯為運算式測試,如上一節中的說明。 通常,這表示該 運算式 的判斷值是 false。 如果 number 沒有對應至在規則運算式模式中使用的編號擷取群組,規則運算式引擎便會擲回 ArgumentException

下列範例是一種範例變化,出現在使用 | 的 Either/Or 模式比對與 | 區段中。 它使用名為 n2 的擷取群組,由兩個位數及後接的連字號所組成。 替代建構會測試是否已在輸入字串中比對這個擷取的群組。 如果有的話,替代建構就會嘗試比對美國的最後七位數。 雇主識別碼 (EIN)。 如果沒有的話,它就會嘗試比對美國 社會安全號碼 (SSN)。

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b(?<n2>\d{2}-)*(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b"
      Dim input As String = "01-9999999 020-333333 777-88-9999"
      Console.WriteLine("Matches for {0}:", pattern)
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
      Next   
   End Sub
End Module
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(?<n2>\d{2}-)*(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example displays the following output:
//       Matches for \b(?<n2>\d{2}-)*(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22

規則運算式模式 \b(?<n2>\d{2}-)*(?(n2)\d{7}|\d{3}-\d{2}-\d{4})\b 的解譯方式如下表所示。

模式

描述

\b

從字緣開始。

(?<n2>\d{2}-)*

比對出現零次或一次的兩個數字,後接連字號。 將此擷取群組命名為 n2。

(?(n2)

測試 n2 是否在輸入字串中符合。

)\d{7}

如果 n2 符合,便會比對七個十進位數字。

|\d{3}-\d{2}-\d{4}

如果 n2 不符合,便會比對三個十進位數字、連字號、兩個十進位數字、另一個連字號,以及四個十進位數字。

\b

比對字緣。

本範例的變體使用編號的群組,而不是具名群組,如以下範例所示。 它的規則運算式模式是 \b(\d{2}-)*(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b。

Imports System.Text.RegularExpressions

Module Example
   Public Sub Main()
      Dim pattern As String = "\b(\d{2}-)*(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b"
      Dim input As String = "01-9999999 020-333333 777-88-9999"
      Console.WriteLine("Matches for {0}:", pattern)
      For Each match As Match In Regex.Matches(input, pattern)
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index)
      Next   
   End Sub
End Module
' The example displays the following output:
'       Matches for \b(\d{2}-)*(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
'          01-9999999 at position 0
'          777-88-9999 at position 22
using System;
using System.Text.RegularExpressions;

public class Example
{
   public static void Main()
   {
      string pattern = @"\b(\d{2}-)*(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b";
      string input = "01-9999999 020-333333 777-88-9999";
      Console.WriteLine("Matches for {0}:", pattern);
      foreach (Match match in Regex.Matches(input, pattern))
         Console.WriteLine("   {0} at position {1}", match.Value, match.Index);
   }
}
// The example display the following output:
//       Matches for \b(\d{2}-)*(?(1)\d{7}|\d{3}-\d{2}-\d{4})\b:
//          01-9999999 at position 0
//          777-88-9999 at position 22

回到頁首

請參閱

概念

規則運算式語言項目