# 規則運算式中的分組建構Grouping Constructs in Regular Expressions

• 比對輸入字串中重複的子運算式。Match a subexpression that is repeated in the input string.

• 將數量詞套用至具有多個規則運算式語言項目的子運算式。Apply a quantifier to a subexpression that has multiple regular expression language elements. 如需數量詞的詳細資訊，請參閱 QuantifiersFor more information about quantifiers, see Quantifiers.

• Regex.ReplaceMatch.Result 方法傳回的字串中包含子運算式。Include a subexpression in the string that is returned by the Regex.Replace and Match.Result methods.

• Match.Groups 屬性擷取個別子運算式，再全部一起與相符文字分開處理。Retrieve individual subexpressions from the Match.Groups property and process them separately from the matched text as a whole.

## 相符子運算式Matched Subexpressions

( 子運算式 )( subexpression )

• 在規則運算式中使用反向參考建構。By using the backreference construct within the regular expression. 使用語法 \number(其中 where number 是所擷取子運算式的序號)，在相同的規則運算式中參考相符子運算式。The matched subexpression is referenced in the same regular expression by using the syntax \number, where number is the ordinal number of the captured subexpression.

• 在規則運算式中使用具名的反向參考建構。By using the named backreference construct within the regular expression. 使用語法 \k<name>(其中 where name 是擷取群組的名稱) 或 \k<number>(其中 where number 是擷取群組的序號)，在相同的規則運算式中參考相符子運算式。The matched subexpression is referenced in the same regular expression by using the syntax \k<name>, where name is the name of a capturing group, or \k<number>, where number is the ordinal number of a capturing group. 擷取群組的預設名稱與其序號相同。A capturing group has a default name that is identical to its ordinal number. 如需詳細資訊，請參閱本主題稍後的 具名的相符子運算式For more information, see Named matched subexpressions later in this topic.

• $number$ Regex.Replace number Match.Result 取代順序，其中 number 是所擷取子運算式的序號)，在相同的規則運算式中參考相符子運算式。By using the $number replacement sequence in a Regex.Replace or Match.Result method call, where number is the ordinal number of the captured subexpression. • 以程式設計方式，使用 GroupCollection 屬性傳回的 Match.Groups 物件。Programmatically, by using the GroupCollection object returned by the Match.Groups property. 集合中位置為零的成員代表整個規則運算式相符。The member at position zero in the collection represents the entire regular expression match. 每個後續成員各代表一個相符子運算式。Each subsequent member represents a matched subexpression. 如需詳細資訊，請參閱 Grouping Constructs and Regular Expression Objects 一節。For more information, see the Grouping Constructs and Regular Expression Objects section. 下列範例說明可識別文字中重複文字的規則運算式。The following example illustrates a regular expression that identifies duplicated words in text. 規則運算式模式的兩個擷取群組代表重複文字的兩個執行個體。The regular expression pattern's two capturing groups represent the two instances of the duplicated word. 擷取第二個執行個體是為了報告其於輸入字串中的開始位置。The second instance is captured to report its starting position in the input string. using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string pattern = @"(\w+)\s(\1)"; string input = "He said that that was the the correct answer."; foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase)) Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.", match.Groups[1].Value, match.Groups[1].Index, match.Groups[2].Index); } } // The example displays the following output: // Duplicate 'that' found at positions 8 and 13. // Duplicate 'the' found at positions 22 and 26.  Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "(\w+)\s(\1)\W" Dim input As String = "He said that that was the the correct answer." For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase) Console.WriteLine("Duplicate '{0}' found at positions {1} and {2}.", _ match.Groups(1).Value, match.Groups(1).Index, match.Groups(2).Index) Next End Sub End Module ' The example displays the following output: ' Duplicate 'that' found at positions 8 and 13. ' Duplicate 'the' found at positions 22 and 26.  規則運算式模式如下：The regular expression pattern is the following: (\w+)\s(\1)\W  下表顯示規則運算式模式的解譯方式。The following table shows how the regular expression pattern is interpreted. 模式Pattern 說明Description (\w+) 比對一個或多個文字字元。Match one or more word characters. 這是第一個擷取群組。This is the first capturing group. \s 比對空白字元。Match a white-space character. (\1) 比對第一個擷取群組中的字串。Match the string in the first captured group. 這是第二個擷取群組。This is the second capturing group. 此範例將其指派給擷取的群組，以便從 Match.Index 物件。The example assigns it to a captured group so that the starting position of the duplicate word can be retrieved from the Match.Index property. \W 比對非文字字元，包括空格和標點符號。Match a non-word character, including white space and punctuation. 如此可防止規則運算式模式比對以第一個擷取群組中的文字為開頭的文字。This prevents the regular expression pattern from matching a word that starts with the word from the first captured group. ## 具名的相符子運算式Named Matched Subexpressions 下列分組建構會擷取相符子運算式，並可讓您依名稱或依號碼加以存取。The following grouping construct captures a matched subexpression and lets you access it by name or by number: (?<name>subexpression)  或：or: (?'name'subexpression)  其中 name 是有效的群組名稱，而 subexpression 是任何有效的規則運算式模式。where name is a valid group name, and subexpression is any valid regular expression pattern. name 絕不能包含任何標點符號字元，而且不能以數字開頭。name must not contain any punctuation characters and cannot begin with a number. 注意 如果規則運算式模式比對方法的 RegexOptions 參數包含 RegexOptions.ExplicitCapture 旗標，或這個子運算式套用了 n 選項 (請參閱本主題稍後的 群組選項 )，則擷取子運算式的唯一方式，就是明確地為擷取群組命名。If the RegexOptions parameter of a regular expression pattern matching method includes the RegexOptions.ExplicitCapture flag, or if the n option is applied to this subexpression (see Group options later in this topic), the only way to capture a subexpression is to explicitly name capturing groups. 您可以用下列方式來存取具名的擷取群組：You can access named captured groups in the following ways: • 在規則運算式中使用具名的反向參考建構。By using the named backreference construct within the regular expression. 使用語法 \k<name>(其中 where name 是所擷取子運算式的名稱)，在相同的規則運算式中參考相符子運算式。The matched subexpression is referenced in the same regular expression by using the syntax \k<name>, where name is the name of the captured subexpression. • 在規則運算式中使用反向參考建構。By using the backreference construct within the regular expression. 使用語法 \number(其中 where number 是所擷取子運算式的序號)，在相同的規則運算式中參考相符子運算式。The matched subexpression is referenced in the same regular expression by using the syntax \number, where number is the ordinal number of the captured subexpression. 具名的相符子運算式會在相符子運算式之後，由左至右連續編號。Named matched subexpressions are numbered consecutively from left to right after matched subexpressions. • ${name} $Regex.Replace number Match.Result 取代順序，其中 name 是所擷取子運算式的名稱)，在相同的規則運算式中參考相符子運算式。By using the ${name} replacement sequence in a Regex.Replace or Match.Result method call, where name is the name of the captured subexpression.

• Regex.ReplaceMatch.Result 方法呼叫中使用 $number 取代序列，其中 number 是所擷取子運算式的序號。By using the $number replacement sequence in a Regex.Replace or Match.Result method call, where number is the ordinal number of the captured subexpression.

• 以程式設計方式，使用 GroupCollection 屬性傳回的 Match.Groups 物件。Programmatically, by using the GroupCollection object returned by the Match.Groups property. 集合中位置為零的成員代表整個規則運算式相符。The member at position zero in the collection represents the entire regular expression match. 每個後續成員各代表一個相符子運算式。Each subsequent member represents a matched subexpression. 具名的擷取群組儲存在集合中，編號的擷取群組之後。Named captured groups are stored in the collection after numbered captured groups.

• 以程式設計方式，提供子運算式名稱給 GroupCollection 物件的索引子 (在 C# 中) 或其 Item[String] 屬性 (在 Visual Basic 中)。Programmatically, by providing the subexpression name to the GroupCollection object's indexer (in C#) or to its Item[String] property (in Visual Basic).

numberNumber 名稱Name 模式Pattern
00 0 (預設名稱)0 (default name) ((?<One>abc)\d+)?(?<Two>xyz)(.*)
11 1 (預設名稱)1 (default name) ((?<One>abc)\d+)
22 2 (預設名稱)2 (default name) (.*)
33 One (?<One>abc)
44 Two (?<Two>xyz)

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string pattern = @"(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)";
string input = "He said that that was the the correct answer.";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.",
match.Groups["duplicateWord"].Value, match.Groups["duplicateWord"].Index,
match.Groups["nextWord"].Value);

}
}
// The example displays the following output:
//       A duplicate 'that' at position 8 is followed by 'was'.
//       A duplicate 'the' at position 22 is followed by 'correct'.

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim pattern As String = "(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)"
Dim input As String = "He said that that was the the correct answer."
Console.WriteLine(Regex.Matches(input, pattern, RegexOptions.IgnoreCase).Count)
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine("A duplicate '{0}' at position {1} is followed by '{2}'.", _
match.Groups("duplicateWord").Value, match.Groups("duplicateWord").Index, _
match.Groups("nextWord").Value)
Next
End Sub
End Module
' The example displays the following output:
'    A duplicate 'that' at position 8 is followed by 'was'.
'    A duplicate 'the' at position 22 is followed by 'correct'.


(?<duplicateWord>\w+)\s\k<duplicateWord>\W(?<nextWord>\w+)


(?<duplicateWord>\w+) 比對一個或多個文字字元。Match one or more word characters. 將此擷取群組命名為 duplicateWordName this capturing group duplicateWord.
\s 比對空白字元。Match a white-space character.
\k<duplicateWord> 從名為 duplicateWord的擷取群組比對字串。Match the string from the captured group that is named duplicateWord.
\W 比對非文字字元，包括空格和標點符號。Match a non-word character, including white space and punctuation. 如此可防止規則運算式模式比對以第一個擷取群組中的文字為開頭的文字。This prevents the regular expression pattern from matching a word that starts with the word from the first captured group.
(?<nextWord>\w+) 比對一個或多個文字字元。Match one or more word characters. 將此擷取群組命名為 nextWordName this capturing group nextWord.

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
String pattern = @"\D+(?<digit>\d+)\D+(?<digit>\d+)?";
String[] inputs = { "abc123def456", "abc123def" };
foreach (var input in inputs) {
Match m = Regex.Match(input, pattern);
if (m.Success) {
Console.WriteLine("Match: {0}", m.Value);
for (int grpCtr = 1; grpCtr < m.Groups.Count; grpCtr++) {
Group grp = m.Groups[grpCtr];
Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value);
for (int capCtr = 0; capCtr < grp.Captures.Count; capCtr++)
Console.WriteLine("   Capture {0}: {1}", capCtr,
grp.Captures[capCtr].Value);
}
}
else {
Console.WriteLine("The match failed.");
}
Console.WriteLine();
}
}
}
// The example displays the following output:
//       Match: abc123def456
//       Group 1: 456
//          Capture 0: 123
//          Capture 1: 456
//
//       Match: abc123def
//       Group 1: 123
//          Capture 0: 123

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim pattern As String = "\D+(?<digit>\d+)\D+(?<digit>\d+)?"
Dim inputs() As String = { "abc123def456", "abc123def" }
For Each input As String In inputs
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Match: {0}", m.Value)
For grpCtr As Integer = 1 to m.Groups.Count - 1
Dim grp As Group = m.Groups(grpCtr)
Console.WriteLine("Group {0}: {1}", grpCtr, grp.Value)
For capCtr As Integer = 0 To grp.Captures.Count - 1
Console.WriteLine("   Capture {0}: {1}", capCtr,
grp.Captures(capCtr).Value)
Next
Next
Else
Console.WriteLine("The match failed.")
End If
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
'       Match: abc123def456
'       Group 1: 456
'          Capture 0: 123
'          Capture 1: 456
'
'       Match: abc123def
'       Group 1: 123
'          Capture 0: 123


\D+ 比對一個或更多非十進位數字字元。Match one or more non-decimal digit characters.
(?<digit>\d+) 比對一個或更多十進位數字字元。Match one or more decimal digit characters. 指派 digit 具名群組的比對。Assign the match to the digit named group.
\D+ 比對一個或更多非十進位數字字元。Match one or more non-decimal digit characters.
(?<digit>\d+)? 比對一或多個十進位數字字元的零次或一次發生。Match zero or one occurrence of one or more decimal digit characters. 指派 digit 具名群組的比對。Assign the match to the digit named group.

## 平衡群組定義Balancing Group Definitions

(?<name1-name2>subexpression)


(?'name1-name2' subexpression)


using System;
using System.Text.RegularExpressions;

class Example
{
public static void Main()
{
string pattern = "^[^<>]*" +
"(" +
"((?'Open'<)[^<>]*)+" +
"((?'Close-Open'>)[^<>]*)+" +
")*" +
"(?(Open)(?!))$"; string input = "<abc><mno<xyz>>"; Match m = Regex.Match(input, pattern); if (m.Success == true) { Console.WriteLine("Input: \"{0}\" \nMatch: \"{1}\"", input, m); int grpCtr = 0; foreach (Group grp in m.Groups) { Console.WriteLine(" Group {0}: {1}", grpCtr, grp.Value); grpCtr++; int capCtr = 0; foreach (Capture cap in grp.Captures) { Console.WriteLine(" Capture {0}: {1}", capCtr, cap.Value); capCtr++; } } } else { Console.WriteLine("Match failed."); } } } // The example displays the following output: // Input: "<abc><mno<xyz>>" // Match: "<abc><mno<xyz>>" // Group 0: <abc><mno<xyz>> // Capture 0: <abc><mno<xyz>> // Group 1: <mno<xyz>> // Capture 0: <abc> // Capture 1: <mno<xyz>> // Group 2: <xyz // Capture 0: <abc // Capture 1: <mno // Capture 2: <xyz // Group 3: > // Capture 0: > // Capture 1: > // Capture 2: > // Group 4: // Group 5: mno<xyz> // Capture 0: abc // Capture 1: xyz // Capture 2: mno<xyz>  Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "^[^<>]*" & _ "(" + "((?'Open'<)[^<>]*)+" & _ "((?'Close-Open'>)[^<>]*)+" + ")*" & _ "(?(Open)(?!))$"
Dim input As String = "<abc><mno<xyz>>"
Dim rgx AS New Regex(pattern)'
Dim m As Match = Regex.Match(input, pattern)
If m.Success Then
Console.WriteLine("Input: ""{0}"" " & vbCrLf & "Match: ""{1}""", _
input, m)
Dim grpCtr As Integer = 0
For Each grp As Group In m.Groups
Console.WriteLine("   Group {0}: {1}", grpCtr, grp.Value)
grpCtr += 1
Dim capCtr As Integer = 0
For Each cap As Capture In grp.Captures
Console.WriteLine("      Capture {0}: {1}", capCtr, cap.Value)
capCtr += 1
Next
Next
Else
Console.WriteLine("Match failed.")
End If
End Sub
End Module
' The example displays the following output:
'       Input: "<abc><mno<xyz>>"
'       Match: "<abc><mno<xyz>>"
'          Group 0: <abc><mno<xyz>>
'             Capture 0: <abc><mno<xyz>>
'          Group 1: <mno<xyz>>
'             Capture 0: <abc>
'             Capture 1: <mno<xyz>>
'          Group 2: <xyz
'             Capture 0: <abc
'             Capture 1: <mno
'             Capture 2: <xyz
'          Group 3: >
'             Capture 0: >
'             Capture 1: >
'             Capture 2: >
'          Group 4:
'          Group 5: mno<xyz>
'             Capture 0: abc
'             Capture 1: xyz
'             Capture 2: mno<xyz>


^[^<>]*(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))$ 規則運算式解譯如下：The regular expression is interpreted as follows: 模式Pattern 說明Description ^ 從字串開頭開始。Begin at the start of the string. [^<>]* 比對非左右角括號的零或多個字元。Match zero or more characters that are not left or right angle brackets. (?'Open'<) 比對左角括號，並將其指派給名為 Open的群組。Match a left angle bracket and assign it to a group named Open. [^<>]* 比對非左右角括號的零或多個字元。Match zero or more characters that are not left or right angle brackets. ((?'Open'<)[^<>]*)+ 比對出現一或數次、後面接零或多個非左右角括號字元的左角括號。Match one or more occurrences of a left angle bracket followed by zero or more characters that are not left or right angle brackets. 這是第二個擷取群組。This is the second capturing group. (?'Close-Open'>) 比對右角括號，將 Open 群組與目前群組之間的子字串指派給 Close 群組，並刪除 Open 群組的定義。Match a right angle bracket, assign the substring between the Open group and the current group to the Close group, and delete the definition of the Open group. [^<>]* 比對出現零或數次、非左右角括號的任何字元。Match zero or more occurrences of any character that is neither a left nor a right angle bracket. ((?'Close-Open'>)[^<>]*)+ 比對出現一或數次、後接零或多個非左右角括號字元的右角括號。Match one or more occurrences of a right angle bracket, followed by zero or more occurrences of any character that is neither a left nor a right angle bracket. 比對右角括號時，將 Open 群組與目前群組之間的子字串指派給 Close 群組，並刪除 Open 群組的定義。When matching the right angle bracket, assign the substring between the Open group and the current group to the Close group, and delete the definition of the Open group. 這是第三個擷取群組。This is the third capturing group. (((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)* 比對出現零或數次的下列模式：出現一或數次的左角括號，後接零或多個非角括號字元，後接出現一或數次的右角括號，後接出現零或數次的非角括號。Match zero or more occurrences of the following pattern: one or more occurrences of a left angle bracket, followed by zero or more non-angle bracket characters, followed by one or more occurrences of a right angle bracket, followed by zero or more occurrences of non-angle brackets. 比對右角括號時，刪除 Open 群組的定義，並將 Open 群組與目前群組之間的子字串指派給 Close 群組。When matching the right angle bracket, delete the definition of the Open group, and assign the substring between the Open group and the current group to the Close group. 這是第一個擷取群組。This is the first capturing group. (?(Open)(?!)) 如果 Open 群組存在，若可以比對空字串，則放棄比對，但不要將字串中的規則運算式引擎的位置向前移動。If the Open group exists, abandon the match if an empty string can be matched, but do not advance the position of the regular expression engine in the string. 這是零寬度右不合樣 (Negative Lookahead) 判斷提示。This is a zero-width negative lookahead assertion. 因為空字串一律以隱含方式存在於輸入字串中，所以此比對一定會失敗。Because an empty string is always implicitly present in an input string, this match always fails. 此比對失敗表示角括號不平衡。Failure of this match indicates that the angle brackets are not balanced. $ 比對輸入字串的結尾。Match the end of the input string.

11 ^ 從輸入字串的開頭開始比對。Starts the match at the beginning of the input string
22 [^<>]* 在左角括號之前尋找非角括號字元；沒有找到配對。Looks for non-angle bracket characters before the left angle bracket;finds no matches.
33 (((?'Open'<) 比對 "<abc>" 中的左角括號，並將其指派給 Open 群組。Matches the left angle bracket in "<abc>" and assigns it to the Open group.
44 [^<>]* 比對 "abc"。Matches "abc".
55 )+ "<abc" 是第二個擷取群組的值。"<abc" is the value of the second captured group.

66 ((?'Close-Open'>) 比對 "<abc>" 中的右角括號，將 "abc" (介於 Open 群組與右角括號之間的子字串) 指派給 Open 群組，並刪除 Close 群組的目前值 ("<")，使其空白。Matches the right angle bracket in "<abc>", assigns "abc", which is the substring between the Open group and the right angle bracket, to the Close group, and deletes the current value ("<") of the Open group, leaving it empty.
77 [^<>]* 在右角括號之後尋找非角括號字元；沒有找到配對。Looks for non-angle bracket characters after the right angle bracket; finds no matches.
88 )+ 第三個擷取群組的值是 ">"。The value of the third captured group is ">".

99 )* 第一個擷取群組的值是 "<abc>"。The value of the first captured group is "<abc>".

1010 (((?'Open'<) 比對 "<mno" 中的左角括弧，並將其指派給 Open 群組。Matches the left angle bracket in "<mno" and assigns it to the Open group. Group.Captures 集合現在有單一值 "<"。Its Group.Captures collection now has a single value, "<".
1111 [^<>]* 比對 "mno"。Matches "mno".
1212 )+ "<mno" 是第二個擷取群組的值。"<mno" is the value of the second captured group.

1313 (((?'Open'<) 比對 "<xyz>" 中的左角括號，並將其指派給 Open 群組。Matches the left angle bracket in "<xyz>" and assigns it to the Open group. Open 群組的 Group.Captures 集合現在包含兩個擷取："<mno" 的左角括弧，以及 "<xyz>" 的左角括弧。The Group.Captures collection of the Open group now includes two captures: the left angle bracket from "<mno", and the left angle bracket from "<xyz>".
1414 [^<>]* 比對 "xyz"。Matches "xyz".
1515 )+ "<xyz" 是第二個擷取群組的值。"<xyz" is the value of the second captured group.

1616 ((?'Close-Open'>) 比對 "<xyz>" 的右角括弧。Matches the right angle bracket in "<xyz>". "xyz"，將 Open 群組與右角括弧之間的子字串指派給 Close 群組，並刪除 Open 群組目前的值。"xyz", assigns the substring between the Open group and the right angle bracket to the Close group, and deletes the current value of the Open group. 先前擷取的值 ("<mno" 中的左角括弧) 會變成 Open 群組目前值。The value of the previous capture (the left angle bracket in "<mno") becomes the current value of the Open group. Open 群組的 Captures 集合現在包含單一擷取："<xyz>" 的左角括號。The Captures collection of the Open group now includes a single capture, the left angle bracket from "<xyz>".
1717 [^<>]* 尋找非角括號字元；沒有找到配對。Looks for non-angle bracket characters; finds no matches.
1818 )+ 第三個擷取群組的值是 ">"。The value of the third captured group is ">".

1919 ((?'Close-Open'>) 比對 "xyz>>" 中的最後一個右角括號，將 "mno<xyz>" (介於 Open 群組與右角括號之間的子字串) 指派給 Close 群組，並刪除 Open 群組的目前值。Matches the final right angle bracket in "xyz>>", assigns "mno<xyz>" (the substring between the Open group and the right angle bracket) to the Close group, and deletes the current value of the Open group. Open 群組現在是空的。The Open group is now empty.
2020 [^<>]* 尋找非角括號字元；沒有找到配對。Looks for non-angle bracket characters; finds no matches.
2121 )+ 第三個擷取群組的值是 ">"。The value of the third captured group is ">".

2222 )* 第一個擷取群組的值是 "<mno<xyz>>"。The value of the first captured group is "<mno<xyz>>".

2323 (?(Open)(?!)) Open 群組未定義，所以未嘗試任何比對。The Open group is not defined, so no match is attempted.
2424 \$ 比對輸入字串的結尾。Matches the end of the input string.

## 非擷取群組Noncapturing Groups

(?:subexpression)


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 ctr = 1; ctr < match.Groups.Count; ctr++)
Console.WriteLine("   Group {0}: {1}", ctr, match.Groups[ctr].Value);
}
}
// The example displays the following output:
//       Match: This is a short sentence.

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim pattern As String = "(?:\b(?:\w+)\W*)+\."
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: {0}", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine("   Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End Sub
End Module
' The example displays the following output:
'       Match: This is a short sentence.


\b 開始字緣比對。Begin the match at a word boundary.
(?:\w+) 比對一個或多個文字字元。Match one or more word characters. 請勿將相符的文字指派給擷取群組。Do not assign the matched text to a captured group.
\W* 比對零或多個非文字字元。Match zero or more non-word characters.
(?:\b(?:\w+)\W*)+ 比對下列模式一次或多次：以字邊界開頭的一或多個文字字元，後面接零或多個非文字字元。Match the pattern of one or more word characters starting at a word boundary, followed by zero or more non-word characters, one or more times. 請勿將相符的文字指派給擷取群組。Do not assign the matched text to a captured group.
\. 比對句點。Match a period.

## 群組選項Group Options

(?imnsx-imnsx: 子運算式 )(?imnsx-imnsx: subexpression )

\b 開始字緣比對。Begin the match at a word boundary.
(?ix: d \w+) 使用不區分大小寫比對，並忽略此模式中的空格，比對後面接一或多個文字字元的 "d"。Using case-insensitive matching and ignoring white space in this pattern, match a "d" followed by one or more word characters.
\s 比對空白字元。Match a white-space character.
string pattern = @"\b(?ix: d \w+)\s";
string input = "Dogs are decidedly good pets.";

foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("'{0}// found at index {1}.", match.Value, match.Index);
// The example displays the following output:
//    'Dogs // found at index 0.
//    'decidedly // found at index 9.

Dim pattern As String = "\b(?ix: d \w+)\s"
Dim input As String = "Dogs are decidedly good pets."

For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("'{0}' found at index {1}.", match.Value, match.Index)
Next
' The example displays the following output:
'    'Dogs ' found at index 0.
'    'decidedly ' found at index 9.


(?= 子運算式 )(?= subexpression )

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string pattern = @"\b\w+(?=\sis\b)";
string[] inputs = { "The dog is a Malamute.",
"The island has beautiful birds.",
"The pitch missed home plate.",
"Sunday is a weekend day." };

foreach (string input in inputs)
{
Match match = Regex.Match(input, pattern);
if (match.Success)
Console.WriteLine("'{0}' precedes 'is'.", match.Value);
else
Console.WriteLine("'{0}' does not match the pattern.", input);
}
}
}
// The example displays the following output:
//    'dog' precedes 'is'.
//    'The island has beautiful birds.' does not match the pattern.
//    'The pitch missed home plate.' does not match the pattern.
//    'Sunday' precedes 'is'.

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim pattern As String = "\b\w+(?=\sis\b)"
Dim inputs() As String = { "The dog is a Malamute.", _
"The island has beautiful birds.", _
"The pitch missed home plate.", _
"Sunday is a weekend day." }

For Each input As String In inputs
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("'{0}' precedes 'is'.", match.Value)
Else
Console.WriteLine("'{0}' does not match the pattern.", input)
End If
Next
End Sub
End Module
' The example displays the following output:
'       'dog' precedes 'is'.
'       'The island has beautiful birds.' does not match the pattern.
'       'The pitch missed home plate.' does not match the pattern.
'       'Sunday' precedes 'is'.


\b 開始字緣比對。Begin the match at a word boundary.
\w+ 比對一個或多個文字字元。Match one or more word characters.
(?=\sis\b) 判定文字字元後面是否接著空格字元和字串 "is"，在字邊界結束。Determine whether the word characters are followed by a white-space character and the string "is", which ends on a word boundary. 若是如此，比對將會成功。If so, the match is successful.

(?! 子運算式 )(?! subexpression )

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string pattern = @"\b(?!un)\w+\b";
string input = "unite one unethical ethics use untie ultimate";
foreach (Match match in Regex.Matches(input, pattern, RegexOptions.IgnoreCase))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
//       one
//       ethics
//       use
//       ultimate

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim pattern As String = "\b(?!un)\w+\b"
Dim input As String = "unite one unethical ethics use untie ultimate"
For Each match As Match In Regex.Matches(input, pattern, RegexOptions.IgnoreCase)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
'       one
'       ethics
'       use
'       ultimate


\b 開始字緣比對。Begin the match at a word boundary.
(?!un) 判斷下兩個字元是否為 "un"。Determine whether the next two characters are "un". 如果不是，才可能比對。If they are not, a match is possible.
\w+ 比對一個或多個文字字元。Match one or more word characters.
\b 結束字緣比對。End the match at a word boundary.

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string pattern = @"\b\w+\b(?!\p{P})";
string input = "Disconnected, disjointed thoughts in a sentence fragment.";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
//       disjointed
//       thoughts
//       in
//       a
//       sentence

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim pattern As String = "\b\w+\b(?!\p{P})"
Dim input As String = "Disconnected, disjointed thoughts in a sentence fragment."
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
'       disjointed
'       thoughts
'       in
'       a
'       sentence


\b 開始字緣比對。Begin the match at a word boundary.
\w+ 比對一個或多個文字字元。Match one or more word characters.
\b 結束字緣比對。End the match at a word boundary.
\p{P}) 如果下一個字元不是標點符號 (例如句點或逗號)，則比對成功。If the next character is not a punctuation symbol (such as a period or a comma), the match succeeds.

## 零寬度左合樣 (Positive Lookbehind) 判斷提示Zero-Width Positive Lookbehind Assertions

(?<= 子運算式 )(?<= subexpression )

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string input = "2010 1999 1861 2140 2009";
string pattern = @"(?<=\b20)\d{2}\b";

foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine(match.Value);
}
}
// The example displays the following output:
//       10
//       09

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim input As String = "2010 1999 1861 2140 2009"
Dim pattern As String = "(?<=\b20)\d{2}\b"

For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Value)
Next
End Sub
End Module
' The example displays the following output:
'       10
'       09


\d{2} 比對兩個十進位數字。Match two decimal digits.
(?<=\b20) 如果字邊界上的兩個十進位數字前置十進位數字 "20"，則繼續比對。Continue the match if the two decimal digits are preceded by the decimal digits "20" on a word boundary.
\b 結束字緣比對。End the match at a word boundary.

## 零寬度左不合樣 (Negative Lookbehind) 判斷提示Zero-Width Negative Lookbehind Assertions

(?<! 子運算式 )(?<! subexpression )

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string[] dates = { "Monday February 1, 2010",
"Wednesday February 3, 2010",
"Saturday February 6, 2010",
"Sunday February 7, 2010",
"Monday, February 8, 2010" };
string pattern = @"(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b";

foreach (string dateValue in dates)
{
Match match = Regex.Match(dateValue, pattern);
if (match.Success)
Console.WriteLine(match.Value);
}
}
}
// The example displays the following output:
//       February 1, 2010
//       February 3, 2010
//       February 8, 2010

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim dates() As String = { "Monday February 1, 2010", _
"Wednesday February 3, 2010", _
"Saturday February 6, 2010", _
"Sunday February 7, 2010", _
"Monday, February 8, 2010" }
Dim pattern As String = "(?<!(Saturday|Sunday) )\b\w+ \d{1,2}, \d{4}\b"

For Each dateValue As String In dates
Dim match As Match = Regex.Match(dateValue, pattern)
If match.Success Then
Console.WriteLine(match.Value)
End If
Next
End Sub
End Module
' The example displays the following output:
'       February 1, 2010
'       February 3, 2010
'       February 8, 2010


\b 開始字緣比對。Begin the match at a word boundary.
\w+ 比對後接空格字元的一或多個文字字元。Match one or more word characters followed by a white-space character.
\d{1,2}, 比對後接空格字元和逗號的一或兩個十進位數。Match either one or two decimal digits followed by a white-space character and a comma.
\d{4}\b 比對四個十進位數，並且在字邊界上結束比對。Match four decimal digits, and end the match at a word boundary.
(?<!(Saturday|Sunday) ) 如果比對項目前置文字不是後接空格的字串 "Saturday" 或 "Sunday"，則比對成功。If the match is preceded by something other than the strings "Saturday" or "Sunday" followed by a space, the match is successful.

## 非回溯子運算式Nonbacktracking Subexpressions

(?> 子運算式 )(?> subexpression )

using System;
using System.Text.RegularExpressions;

public class Example
{
public static void Main()
{
string[] inputs = { "cccd.", "aaad", "aaaa" };
string back = @"(\w)\1+.\b";
string noback = @"(?>(\w)\1+).\b";

foreach (string input in inputs)
{
Match match1 = Regex.Match(input, back);
Match match2 = Regex.Match(input, noback);
Console.WriteLine("{0}: ", input);

Console.Write("   Backtracking : ");
if (match1.Success)
Console.WriteLine(match1.Value);
else
Console.WriteLine("No match");

Console.Write("   Nonbacktracking: ");
if (match2.Success)
Console.WriteLine(match2.Value);
else
Console.WriteLine("No match");
}
}
}
// The example displays the following output:
//    cccd.:
//       Backtracking : cccd
//       Nonbacktracking: cccd
//    aaaa:
//       Backtracking : aaaa
//       Nonbacktracking: No match

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim inputs() As String = { "cccd.", "aaad", "aaaa" }
Dim back As String = "(\w)\1+.\b"
Dim noback As String = "(?>(\w)\1+).\b"

For Each input As String In inputs
Dim match1 As Match = Regex.Match(input, back)
Dim match2 As Match = Regex.Match(input, noback)
Console.WriteLine("{0}: ", input)

Console.Write("   Backtracking : ")
If match1.Success Then
Console.WriteLine(match1.Value)
Else
Console.WriteLine("No match")
End If

Console.Write("   Nonbacktracking: ")
If match2.Success Then
Console.WriteLine(match2.Value)
Else
Console.WriteLine("No match")
End If
Next
End Sub
End Module
' The example displays the following output:
'    cccd.:
'       Backtracking : cccd
'       Nonbacktracking: cccd
'    aaaa:
'       Backtracking : aaaa
'       Nonbacktracking: No match


(\w) 比對單一文字字元，並將其指派給第一個擷取群組。Match a single word character and assign it to the first capturing group.
\1+ 比對第一個擷取子字串的值一或數次。Match the value of the first captured substring one or more times.
. 比對任何字元。Match any character.
\b 結束字邊界比對。End the match on a word boundary.
(?>(\w)\1+) 比對出現一或數次的重複文字字元，但不要回溯比對字邊界上的最後一個字元。Match one or more occurrences of a duplicated word character, but do not backtrack to match the last character on a word boundary.

## 分組建構和規則運算式物件Grouping Constructs and Regular Expression Objects

• 集合中的第一個 Group 物件 (索引位置為零的物件) 代表整個比對。The first Group object in the collection (the object at index zero) represents the entire match.

• 下一個 Group 物件組合代表未具名 (編號的) 擷取群組。The next set of Group objects represent unnamed (numbered) capturing groups. 其出現順序會依照規則運算式中定義的順序，由左至右。They appear in the order in which they are defined in the regular expression, from left to right. 這些群組的索引值範圍是從 1 到集合中未具名擷取群組的編號。The index values of these groups range from 1 to the number of unnamed capturing groups in the collection. (特定群組的索引同等於其編號的反向參考。(The index of a particular group is equivalent to its numbered backreference. 如需反向參考的詳細資訊，請參閱 Backreference Constructs。)For more information about backreferences, see Backreference Constructs.)

• 最後一個 Group 物件組合代表具名擷取群組。The final set of Group objects represent named capturing groups. 其出現順序會依照規則運算式中定義的順序，由左至右。They appear in the order in which they are defined in the regular expression, from left to right. 第一個具名擷取群組的索引值比最後一個未具名擷取群組的索引值大一。The index value of the first named capturing group is one greater than the index of the last unnamed capturing group. 如果規則運算式中沒有未具名擷取群組，則第一個具名擷取群組的索引值為一。If there are no unnamed capturing groups in the regular expression, the index value of the first named capturing group is one.

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 ctr = 1; ctr < match.Groups.Count; ctr++)
{
Console.WriteLine("   Group {0}: '{1}'", ctr, match.Groups[ctr].Value);
int capCtr = 0;
foreach (Capture capture in match.Groups[ctr].Captures)
{
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'

Imports System.Text.RegularExpressions

Module Example
Public Sub Main()
Dim pattern As String = "(\b(\w+)\W+)+"
Dim input As String = "This is a short sentence."
Dim match As Match = Regex.Match(input, pattern)
Console.WriteLine("Match: '{0}'", match.Value)
For ctr As Integer = 1 To match.Groups.Count - 1
Console.WriteLine("   Group {0}: '{1}'", ctr, match.Groups(ctr).Value)
Dim capCtr As Integer = 0
For Each capture As Capture In match.Groups(ctr).Captures
Console.WriteLine("      Capture {0}: '{1}'", capCtr, capture.Value)
capCtr += 1
Next
Next
End Sub
End Module
' 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'


\b 開始字緣比對。Begin the match at a word boundary.
(\w+) 比對一個或多個文字字元。Match one or more word characters. 這些字元共同構成一個單字。Together, these characters form a word. 這是第二個擷取群組。This is the second capturing group.
\W+ 比對一或多個非文字字元。Match one or more non-word characters.
(\b(\w+)\W+) 一或多次比對一或多個文字字元後面接著一或多個非文字字元的模式。Match the pattern of one or more word characters followed by one or more non-word characters one or more times. 這是第一個擷取群組。This is the first capturing group.