規則運算式物件模型
本主題描述用於處理 .NET Framework 規則運算式的物件模型。 它包含以下各節:
規則運算式引擎
MatchCollection 和 Match 物件
群組集合
擷取的群組
擷取集合
個別擷取
規則運算式引擎
.NET Framework 中的規則運算式引擎是由 Regex 類別代表。 規則運算式引擎會負責剖析和編譯規則運算式,以及執行規則運算式模式與輸入字串的比對作業。 此引擎為 .NET Framework 規則運算式物件模型中的主要元件。
您可以用下列其中一種方式使用規則運算式引擎:
呼叫 Regex 類別的靜態方法。 這些方法參數包括輸入字串和規則運算式模式。 規則運算式引擎會快取用於靜態方法呼叫中的規則運算式,因此重複呼叫使用相同規則運算式的靜態規則運算式方法可提供相當良好的效能。
將規則運算式傳遞給類別建構函式,藉以執行個體化 Regex 物件。 在這種情況下,Regex 物件是不可變的 (唯讀),而且代表與單一規則運算式緊密結合的規則運算式引擎。 因為系統不會快取 Regex 執行個體所使用的規則運算式,所以您不應該使用相同的規則運算式來多次執行個體化 Regex 物件。
您可以呼叫 Regex 類別的方法來執行下列作業:
判斷字串是否符合規則運算式模式。
擷取單一相符項目或第一個相符項目。
擷取所有相符項目。
取代相符的子字串。
將單一字串分割成字串陣列。
下列章節將會說明這些作業。
比對規則運算式模式
如果字串符合模式,Regex.IsMatch 方法會傳回 true,否則就傳回 false。 IsMatch 方法通常用於驗證字串輸入。 例如,下列程式碼可確保字串符合有效的美國社會安全碼。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim values() As String = { "111-22-3333", "111-2-3333"}
Dim pattern As String = "^\d{3}-\d{2}-\d{4}$"
For Each value As String In values
If Regex.IsMatch(value, pattern) Then
Console.WriteLine("{0} is a valid SSN.", value)
Else
Console.WriteLine("{0}: Invalid", value)
End If
Next
End Sub
End Module
' The example displays the following output:
' 111-22-3333 is a valid SSN.
' 111-2-3333: Invalid
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string[] values = { "111-22-3333", "111-2-3333"};
string pattern = @"^\d{3}-\d{2}-\d{4}$";
foreach (string value in values) {
if (Regex.IsMatch(value, pattern))
Console.WriteLine("{0} is a valid SSN.", value);
else
Console.WriteLine("{0}: Invalid", value);
}
}
}
// The example displays the following output:
// 111-22-3333 is a valid SSN.
// 111-2-3333: Invalid
規則運算式模式 ^\d{3}-\d{2}-\d{4}$ 的解譯方式如下表所示。
模式 |
說明 |
---|---|
^ |
比對輸入字串的開頭。 |
\d{3} |
比對三個十進位數字。 |
- |
比對連字號。 |
\d{2} |
比對兩個十進位數字。 |
- |
比對連字號。 |
\d{4} |
比對四個十進位數字。 |
$ |
比對輸入字串的結尾。 |
擷取單一相符項目或第一個相符項目
Regex.Match 方法會傳回 Match 物件,其中包含符合規則運算式模式之第一個子字串的相關資訊。 如果 Match.Success 屬性傳回 true,表示找到相符項目,您就可以透過呼叫 Match.NextMatch 方法,擷取後續相符項目的相關資訊。 這些方法呼叫可以繼續進行,直到 Match.Success 屬性傳回 false 為止。 例如,下列程式碼會使用 Regex.Match(String, String) 方法來尋找字串中重複字的第一個項目。 然後,它會呼叫 Match.NextMatch 方法來尋找任何其他項目。 此範例會在每次方法呼叫之後檢查 Match.Success 屬性,以便判斷目前的比對是否成功,以及 Match.NextMatch 方法的呼叫是否應該繼續。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is a a farm that that raises dairy cattle."
Dim pattern As String = "\b(\w+)\W+(\1)\b"
Dim match As Match = Regex.Match(input, pattern)
Do While match.Success
Console.WriteLine("Duplicate '{0}' found at position {1}.", _
match.Groups(1).Value, match.Groups(2).Index)
match = match.NextMatch()
Loop
End Sub
End Module
' The example displays the following output:
' Duplicate 'a' found at position 10.
' Duplicate 'that' found at position 22.
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 |
結束字緣比對。 |
擷取所有相符項目
Regex.Matches 方法會傳回 MatchCollection 物件,其中包含規則運算式引擎在輸入字串中找到之所有相符項目的相關資訊。 例如,您可以將上一個範例重寫為呼叫 Matches 方法,而非 Match 和 NextMatch 方法。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "This is a a farm that that raises dairy cattle."
Dim pattern As String = "\b(\w+)\W+(\1)\b"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine("Duplicate '{0}' found at position {1}.", _
match.Groups(1).Value, match.Groups(2).Index)
Next
End Sub
End Module
' The example displays the following output:
' Duplicate 'a' found at position 10.
' Duplicate 'that' found at position 22.
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";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("Duplicate '{0}' found at position {1}.",
match.Groups[1].Value, match.Groups[2].Index);
}
}
// The example displays the following output:
// Duplicate 'a' found at position 10.
// Duplicate 'that' found at position 22.
取代相符的子字串
Regex.Replace 方法會將符合規則運算式模式的每個子字串取代成指定的字串或規則運算式模式,並且傳回包含取代項目的整個輸入字串。 例如,下列程式碼會在字串中的十進位數字前面加上美國貨幣符號。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\d+\.\d{2}\b"
Dim replacement As String = "$$$&"
Dim input As String = "Total Cost: 103.64"
Console.WriteLine(Regex.Replace(input, pattern, replacement))
End Sub
End Module
' The example displays the following output:
' Total Cost: $103.64
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
規則運算式模式 \b\d+\.\d{2}\b 的解譯方式如下表所示。
模式 |
說明 |
---|---|
\b |
開始字緣比對。 |
\d+ |
比對一個或多個十進位數字。 |
\. |
比對句點。 |
\d{2} |
比對兩個十進位數字。 |
\b |
結束字緣比對。 |
取代模式 $$$& 的解譯方式如下表所示。
模式 |
取代字串 |
---|---|
$$ |
貨幣符號 ($) 字元。 |
$& |
整個相符的子字串。 |
將單一字串分割成字串陣列
Regex.Split 方法會在符合規則運算式定義的位置將輸入字串分割。 例如,下列程式碼會將編號清單中的項目放入字串陣列中。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "1. Eggs 2. Bread 3. Milk 4. Coffee 5. Tea"
Dim pattern As String = "\b\d{1,2}\.\s"
For Each item As String In Regex.Split(input, pattern)
If Not String.IsNullOrEmpty(item) Then
Console.WriteLine(item)
End If
Next
End Sub
End Module
' The example displays the following output:
' Eggs
' Bread
' Milk
' Coffee
' Tea
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "1. Eggs 2. Bread 3. Milk 4. Coffee 5. Tea";
string pattern = @"\b\d{1,2}\.\s";
foreach (string item in Regex.Split(input, pattern))
{
if (! String.IsNullOrEmpty(item))
Console.WriteLine(item);
}
}
}
// The example displays the following output:
// Eggs
// Bread
// Milk
// Coffee
// Tea
規則運算式模式 \b\d{1,2}\.\s 的解譯方式如下表所示。
模式 |
說明 |
---|---|
\b |
開始字緣比對。 |
\d{1,2} |
比對一個或兩個十進位數字。 |
\. |
比對句點。 |
\s |
比對空白字元。 |
MatchCollection 和 Match 物件
Regex 方法會傳回兩個屬於規則運算式物件模型一部分的物件:MatchCollection 物件和 Match 物件。
MatchCollection
Regex.Matches 方法會傳回 MatchCollection 物件,其中包含 Match 物件,而這些物件代表規則運算式引擎找到的所有相符項目 (按照它們出現在輸入字串中的順序列出)。 如果沒有任何相符項目,此方法就會傳回沒有任何成員的 MatchCollection 物件。 MatchCollection.Item 屬性可讓您依照索引 (從零到 MatchCollection.Count 屬性值減一) 存取集合的個別成員。 Item 是集合的索引子 (C#) 和預設屬性 (Visual Basic)。
根據預設,Regex.Matches 方法的呼叫會使用延遲評估來填入 MatchCollection 物件。 存取需要完全填入集合的屬性 (例如 MatchCollection.Count 和 MatchCollection.Item 屬性) 可能會影響效能。 因此,我們建議您使用 MatchCollection.GetEnumerator 方法所傳回的 IEnumerator 物件來存取集合。 個別語言會提供建構 (例如 Visual Basic 中的 For Each 和 C# 中的 foreach),以便包裝集合的 IEnumerator 介面。
下列範例會使用 Regex.Matches(String) 方法,將在輸入字串中找到的所有相符項目填入 MatchCollection 物件。 此範例會列舉集合、將相符項目複製到字串陣列,然後將字元位置記錄在整數陣列中。
Imports System.Collections.Generic
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim matches As MatchCollection
Dim results As New List(Of String)
Dim matchposition As New List(Of Integer)
' Create a new Regex object and define the regular expression.
Dim r As New Regex("abc")
' Use the Matches method to find all matches in the input string.
matches = r.Matches("123abc4abcd")
' Enumerate the collection to retrieve all matches and positions.
For Each match As Match In matches
' Add the match string to the string array.
results.Add(match.Value)
' Record the character position where the match was found.
matchposition.Add(match.Index)
Next
' List the results.
For ctr As Integer = 0 To results.Count - 1
Console.WriteLine("'{0}' found at position {1}.", _
results(ctr), matchposition(ctr))
Next
End Sub
End Module
' The example displays the following output:
' 'abc' found at position 3.
' 'abc' found at position 7.
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
MatchCollection matches;
List<string> results = new List<string>();
List<int> matchposition = new List<int>();
// Create a new Regex object and define the regular expression.
Regex r = new Regex("abc");
// Use the Matches method to find all matches in the input string.
matches = r.Matches("123abc4abcd");
// Enumerate the collection to retrieve all matches and positions.
foreach (Match match in matches)
{
// Add the match string to the string array.
results.Add(match.Value);
// Record the character position where the match was found.
matchposition.Add(match.Index);
}
// List the results.
for (int ctr = 0; ctr < results.Count; ctr++)
Console.WriteLine("'{0}' found at position {1}.",
results[ctr], matchposition[ctr]);
}
}
// The example displays the following output:
// 'abc' found at position 3.
// 'abc' found at position 7.
Match
Match 類別代表單一規則運算式比對的結果。 您可以用兩種方式存取 Match 物件:
從 Regex.Matches 方法所傳回的 MatchCollection 物件中擷取它們。 若要擷取個別 Match 物件,請使用 foreach (C#) 或 For Each...Next(Visual Basic) 建構來逐一查看集合,或使用 MatchCollection.Item 屬性,依照索引或名稱擷取特定 Match 物件。 您也可以依照索引 (從零到集合中的物件數目減一) 逐一查看集合,藉以從集合中擷取個別 Match 物件。 不過,這個方法不會運用延遲評估,因為它會存取 MatchCollection.Count 屬性。
下列範例會使用 foreach 或 For Each...Next 建構來逐一查看集合,藉以從 MatchCollection 物件中擷取個別 Match 物件。 規則運算式只會比對輸入字串中的 "abc" 字串。
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "abc" Dim input As String = "abc123abc456abc789" For Each match As Match In Regex.Matches(input, pattern) Console.WriteLine("{0} found at position {1}.", _ match.Value, match.Index) Next End Sub End Module ' The example displays the following output: ' abc found at position 0. ' abc found at position 6. ' abc found at position 12.
using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string pattern = "abc"; string input = "abc123abc456abc789"; foreach (Match match in Regex.Matches(input, pattern)) Console.WriteLine("{0} found at position {1}.", match.Value, match.Index); } } // The example displays the following output: // abc found at position 0. // abc found at position 6. // abc found at position 12.
呼叫 Regex.Match 方法,以便傳回 Match 物件,代表字串或部分字串中的第一個相符項目。 您可以透過擷取 Match.Success 屬性的值,判斷是否已經找到相符項目。 若要擷取代表後續相符項目的 Match 物件,請重複呼叫 Match.NextMatch 方法,直到傳回之 Match 物件的 Success 屬性是 false 為止。
下列範例會使用 Regex.Match(String, String) 和 Match.NextMatch 方法來比對輸入字串中的 "abc" 字串。
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "abc" Dim input As String = "abc123abc456abc789" Dim match As Match = Regex.Match(input, pattern) Do While match.Success Console.WriteLine("{0} found at position {1}.", _ match.Value, match.Index) match = match.NextMatch() Loop End Sub End Module ' The example displays the following output: ' abc found at position 0. ' abc found at position 6. ' abc found at position 12.
using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string pattern = "abc"; string input = "abc123abc456abc789"; Match match = Regex.Match(input, pattern); while (match.Success) { Console.WriteLine("{0} found at position {1}.", match.Value, match.Index); match = match.NextMatch(); } } } // The example displays the following output: // abc found at position 0. // abc found at position 6. // abc found at position 12.
Match 類別的兩個屬性會傳回集合物件:
Match.Groups 屬性會傳回 GroupCollection 物件,其中包含符合規則運算式模式中擷取群組之子字串的相關資訊。
Group.Captures 屬性會傳回用途有限的 CaptureCollection 物件。 此集合不會針對 Success 屬性是 false 的 Match 物件填入。 否則,它會包含與 Match 物件具有相同資訊的單一 Capture 物件。
如需這些物件的詳細資訊,請參閱本主題後面的群組集合和擷取集合章節。
Match 類別的其他兩個屬性會提供符合項目的相關資訊。 Match.Value 屬性會傳回輸入字串中符合規則運算式模式的子字串。 Match.Index 屬性會傳回符合字串在輸入字串中以零為起始的開始位置。
Match 類別也具有兩個模式比對方法:
Match.NextMatch 方法會在目前 Match 物件所代表的相符項目後面尋找相符項目,並且傳回代表該相符項目的 Match 物件。
Match.Result 方法會針對符合的字串執行指定的取代作業,並且傳回結果。
下列範例會使用 Match.Result 方法,在包含兩個小數位數的數字前面加上一個 $ 符號和一個空格。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b\d+(,\d{3})*\.\d{2}\b"
Dim input As String = "16.32" + vbCrLf + "194.03" + vbCrLf + "1,903,672.08"
For Each match As Match In Regex.Matches(input, pattern)
Console.WriteLine(match.Result("$$ $&"))
Next
End Sub
End Module
' The example displays the following output:
' $ 16.32
' $ 194.03
' $ 1,903,672.08
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
規則運算式模式 \b\d+(,\d{3})*\.\d{2}\b 的定義方式如下表所示。
模式 |
說明 |
---|---|
\b |
開始字緣比對。 |
\d+ |
比對一個或多個十進位數字。 |
(,\d{3})* |
比對零個以上出現的下列模式:逗號後面接著三個十進位數字。 |
\. |
比對小數點字元。 |
\d{2} |
比對兩個十進位數字。 |
\b |
結束字緣比對。 |
取代模式 $$ $& 表示符合的子字串應該取代成貨幣符號 ($) ($$ 模式)、空格以及相符項目的值 ($& 模式)。
回到頁首
群組集合
Match.Groups 屬性會傳回 GroupCollection 物件,其中包含 Group 物件,代表單一相符項目中的擷取群組。 集合中的第一個 Group 物件 (位於索引 0) 代表整個相符項目。 後續的每個物件則代表單一擷取群組的結果。
您可以使用 GroupCollection.Item 屬性來擷取集合中的個別 Group 物件。 您可以依照集合中的序數位置擷取不具名群組,而依照名稱或序數位置擷取具名群組。 不具名擷取會先出現在集合中,並且按照它們出現在規則運算式模式中的順序由左至右建立索引。 具名擷取會在不具名擷取後面,按照它們出現在規則運算式模式中的順序由左至右建立索引。
GroupCollection.Item 屬性是集合的索引子 (C#) 和集合物件的預設值 (Visual Basic)。 這表示,您可以依照索引 (或依照名稱,在具名群組的情況下) 存取個別 Group 物件,如下所示:
Dim group As Group = match.Groups(ctr)
Group group = match.Groups[ctr];
下列範例會定義一個使用群組建構來擷取日期之月份、日和年份的規則運算式。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "\b(\w+)\s(\d{1,2}),\s(\d{4})\b"
Dim input As String = "Born: July 28, 1989"
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
For ctr As Integer = 0 To match.Groups.Count - 1
Console.WriteLine("Group {0}: {1}", ctr, match.Groups(ctr).Value)
Next
End If
End Sub
End Module
' The example displays the following output:
' Group 0: July 28, 1989
' Group 1: July
' Group 2: 28
' Group 3: 1989
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"\b(\w+)\s(\d{1,2}),\s(\d{4})\b";
string input = "Born: July 28, 1989";
Match match = Regex.Match(input, pattern);
if (match.Success)
for (int ctr = 0; ctr < match.Groups.Count; ctr++)
Console.WriteLine("Group {0}: {1}", ctr, match.Groups[ctr].Value);
}
}
// The example displays the following output:
// Group 0: July 28, 1989
// Group 1: July
// Group 2: 28
// Group 3: 1989
規則運算式模式 \b(\w+)\s(\d{1,2}),\s(\d{4})\b 的定義方式如下表所示。
模式 |
說明 |
---|---|
\b |
開始字緣比對。 |
(\w+) |
比對一個或多個文字字元。 這是第一個擷取群組。 |
\s |
比對空白字元。 |
(\d{1,2}) |
比對一個或兩個十進位數字。 這是第二個擷取群組。 |
, |
比對逗號。 |
\s |
比對空白字元。 |
(\d{4}) |
比對四個十進位數字。 這是第三個擷取群組。 |
\b |
結束字緣比對。 |
回到頁首
擷取的群組
Group 類別代表單一擷取群組的結果。 代表定義於規則運算式中之擷取群組的群組物件是由 Match.Groups 屬性所傳回之 GroupCollection 物件的 Item 屬性傳回。 Item 屬性是 Group 類別的索引子 (C#) 和預設屬性 (Visual Basic)。 您也可以使用 foreach 或 For Each 建構來逐一查看集合,藉以擷取個別成員。 如需範例,請參閱上一節。
下列範例會使用巢狀群組建構,將子字串擷取到群組內。 規則運算式模式 (a(b))c 會比對 "abc" 字串。 它會將子字串 "ab" 指派給第一個擷取群組,而將子字串 "b" 指派給第二個擷取群組。
Dim matchposition As New List(Of Integer)
Dim results As New List(Of String)
' Define substrings abc, ab, b.
Dim r As New Regex("(a(b))c")
Dim m As Match = r.Match("abdabc")
Dim i As Integer = 0
While Not (m.Groups(i).Value = "")
' Add groups to string array.
results.Add(m.Groups(i).Value)
' Record character position.
matchposition.Add(m.Groups(i).Index)
i += 1
End While
' Display the capture groups.
For ctr As Integer = 0 to results.Count - 1
Console.WriteLine("{0} at position {1}", _
results(ctr), matchposition(ctr))
Next
' The example displays the following output:
' abc at position 3
' ab at position 3
' b at position 4
List<int> matchposition = new List<int>();
List<string> results = new List<string>();
// Define substrings abc, ab, b.
Regex r = new Regex("(a(b))c");
Match m = r.Match("abdabc");
for (int i = 0; m.Groups[i].Value != ""; i++)
{
// Add groups to string array.
results.Add(m.Groups[i].Value);
// Record character position.
matchposition.Add(m.Groups[i].Index);
}
// Display the capture groups.
for (int ctr = 0; ctr < results.Count; ctr++)
Console.WriteLine("{0} at position {1}",
results[ctr], matchposition[ctr]);
// The example displays the following output:
// abc at position 3
// ab at position 3
// b at position 4
下列範例會使用具名群組建構,從含有 "DATANAME:VALUE" 格式 (規則運算式以冒號 (:) 分隔) 資料的字串中擷取子字串。
Dim r As New Regex("^(?<name>\w+):(?<value>\w+)")
Dim m As Match = r.Match("Section1:119900")
Console.WriteLine(m.Groups("name").Value)
Console.WriteLine(m.Groups("value").Value)
' The example displays the following output:
' Section1
' 119900
Regex 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
規則運算式模式 ^(?<name>\w+):(?<value>\w+) 的定義方式如下表所示。
模式 |
說明 |
---|---|
^ |
在輸入字串的開頭開始比對。 |
(?<name>\w+) |
比對一個或多個文字字元。 這個擷取群組的名稱是 name。 |
: |
比對冒號。 |
(?<value>\w+) |
比對一個或多個文字字元。 這個擷取群組的名稱是 value。 |
Group 類別的屬性會提供擷取之群組的相關資訊:Group.Value 屬性包含擷取的子字串、Group.Index 屬性表示擷取之群組在輸入文字中的起始位置、Group.Length 屬性包含擷取之文字的長度,而 Group.Success 屬性指出是否有子字串符合擷取群組所定義的模式。
將數量詞套用至群組 (如需詳細資訊,請參閱數量詞) 就會以兩種方式修改每個擷取群組中單一擷取的關聯性:
如果 * 或 *? 數量詞 (指定零個以上的相符項目) 套用至群組,擷取群組可能不會在輸入字串中具有相符項目。 如果沒有任何擷取的文字,Group 物件的屬性就會依照下表所示的方式設定。
Group 屬性
值
Success
false
Value
Length
0
下列範例提供一個實例。 在規則運算式模式 aaa(bbb)*ccc 中,第一個擷取群組 (子字串 "bbb") 可以被比對零次或零次以上。 因為輸入字串 "aaaccc" 符合模式,所以擷取群組沒有相符項目。
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "aaa(bbb)*ccc" Dim input As String = "aaaccc" Dim match As Match = Regex.Match(input, pattern) Console.WriteLine("Match value: {0}", match.Value) If match.Groups(1).Success Then Console.WriteLine("Group 1 value: {0}", match.Groups(1).Value) Else Console.WriteLine("The first capturing group has no match.") End If End Sub End Module ' The example displays the following output: ' Match value: aaaccc ' The first capturing group has no match.
using System; using System.Text.RegularExpressions; public class Example { public static void Main() { string pattern = "aaa(bbb)*ccc"; string input = "aaaccc"; Match match = Regex.Match(input, pattern); Console.WriteLine("Match value: {0}", match.Value); if (match.Groups[1].Success) Console.WriteLine("Group 1 value: {0}", match.Groups[1].Value); else Console.WriteLine("The first capturing group has no match."); } } // The example displays the following output: // Match value: aaaccc // The first capturing group has no match.
數量詞可以比對擷取群組所定義之模式的多個項目。 在這種情況下,Group 物件的 Value 和 Length 屬性只會包含最後擷取之子字串的相關資訊。 例如,下列規則運算式會比對以句點結束的單一句子。 它會使用兩個群組建構:第一個建構會擷取個別單字以及空白字元,而第二個建構則擷取個別單字。 如範例的輸出所示,雖然規則運算式成功擷取整個句子,不過第二個擷取群組只會擷取最後一個單字。
Imports System.Text.RegularExpressions Module Example Public Sub Main() Dim pattern As String = "\b((\w+)\s?)+\." Dim input As String = "This is a sentence. This is another sentence." Dim match As Match = Regex.Match(input, pattern) If match.Success Then Console.WriteLine("Match: " + match.Value) Console.WriteLine("Group 2: " + match.Groups(2).Value) End If End Sub End Module ' The example displays the following output: ' Match: This is a sentence. ' Group 2: sentence
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
回到頁首
擷取集合
Group 物件只會包含最後擷取的相關資訊。 不過,您仍然可以透過 Group.Captures 屬性所傳回的 CaptureCollection 物件,使用擷取群組所建立的整個擷取集。 此集合的每個成員都是 Capture 物件,代表該擷取群組所建立的擷取,並且按照擷取它們的順序列出 (因此,按照輸入字串中由左至右比對擷取之字串的順序列出)。 您可以用下列其中一種方式,從集合中擷取個別 Capture 物件:
使用建構 (例如 foreach (C#) 或 For Each (Visual Basic)) 來逐一查看集合。
使用 CaptureCollection.Item 屬性來依照索引擷取特定物件。 Item 屬性是 CaptureCollection 物件的預設屬性 (Visual Basic) 或索引子 (C#)。
如果數量詞沒有套用至擷取群組,CaptureCollection 物件就會包含較不相關的單一 Capture 物件,因為它會提供與其 Group 物件相同之相符項目的相關資訊。 如果數量詞套用至擷取群組,CaptureCollection 物件就會包含擷取群組所建立的所有擷取,而且此集合的最後一個成員與 Group 物件代表相同的擷取。
例如,如果您使用規則運算式模式 ((a(b))c)+ (其中 + 數量詞指定一個或多個相符項目) 來擷取 "abcabcabc" 字串中的相符項目,每個 Group 物件的 CaptureCollection 物件都會包含三個成員。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim pattern As String = "((a(b))c)+"
Dim input As STring = "abcabcabc"
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("Match: '{0}' at position {1}", _
match.Value, match.Index)
Dim groups As GroupCollection = match.Groups
For ctr As Integer = 0 To groups.Count - 1
Console.WriteLine(" Group {0}: '{1}' at position {2}", _
ctr, groups(ctr).Value, groups(ctr).Index)
Dim captures As CaptureCollection = groups(ctr).Captures
For ctr2 As Integer = 0 To captures.Count - 1
Console.WriteLine(" Capture {0}: '{1}' at position {2}", _
ctr2, captures(ctr2).Value, captures(ctr2).Index)
Next
Next
End If
End Sub
End Module
' The example dosplays the following output:
' Match: 'abcabcabc' at position 0
' Group 0: 'abcabcabc' at position 0
' Capture 0: 'abcabcabc' at position 0
' Group 1: 'abc' at position 6
' Capture 0: 'abc' at position 0
' Capture 1: 'abc' at position 3
' Capture 2: 'abc' at position 6
' Group 2: 'ab' at position 6
' Capture 0: 'ab' at position 0
' Capture 1: 'ab' at position 3
' Capture 2: 'ab' at position 6
' Group 3: 'b' at position 7
' Capture 0: 'b' at position 1
' Capture 1: 'b' at position 4
' Capture 2: 'b' at position 7
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = "((a(b))c)+";
string input = "abcabcabc";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
Console.WriteLine("Match: '{0}' at position {1}",
match.Value, match.Index);
GroupCollection groups = match.Groups;
for (int ctr = 0; ctr < groups.Count; ctr++) {
Console.WriteLine(" Group {0}: '{1}' at position {2}",
ctr, groups[ctr].Value, groups[ctr].Index);
CaptureCollection captures = groups[ctr].Captures;
for (int ctr2 = 0; ctr2 < captures.Count; ctr2++) {
Console.WriteLine(" Capture {0}: '{1}' at position {2}",
ctr2, captures[ctr2].Value, captures[ctr2].Index);
}
}
}
}
}
// The example displays the following output:
// Match: 'abcabcabc' at position 0
// Group 0: 'abcabcabc' at position 0
// Capture 0: 'abcabcabc' at position 0
// Group 1: 'abc' at position 6
// Capture 0: 'abc' at position 0
// Capture 1: 'abc' at position 3
// Capture 2: 'abc' at position 6
// Group 2: 'ab' at position 6
// Capture 0: 'ab' at position 0
// Capture 1: 'ab' at position 3
// Capture 2: 'ab' at position 6
// Group 3: 'b' at position 7
// Capture 0: 'b' at position 1
// Capture 1: 'b' at position 4
// Capture 2: 'b' at position 7
下列範例會使用規則運算式 (Abc)+,在 "XYZAbcAbcAbcXYZAbcAb" 字串中尋找一個或多個 "Abc" 字串的連續項目。 此範例說明如何使用 Group.Captures 屬性來傳回多個擷取之子字串的群組。
Dim counter As Integer
Dim m As Match
Dim cc As CaptureCollection
Dim gc As GroupCollection
' Look for groupings of "Abc".
Dim r As New Regex("(Abc)+")
' Define the string to search.
m = r.Match("XYZAbcAbcAbcXYZAbcAb")
gc = m.Groups
' Display the number of groups.
Console.WriteLine("Captured groups = " & gc.Count.ToString())
' Loop through each group.
Dim i, ii As Integer
For i = 0 To gc.Count - 1
cc = gc(i).Captures
counter = cc.Count
' Display the number of captures in this group.
Console.WriteLine("Captures count = " & counter.ToString())
' Loop through each capture in the group.
For ii = 0 To counter - 1
' Display the capture and its position.
Console.WriteLine(cc(ii).ToString() _
& " Starts at character " & cc(ii).Index.ToString())
Next ii
Next i
' The example displays the following output:
' Captured groups = 2
' Captures count = 1
' AbcAbcAbc Starts at character 3
' Captures count = 3
' Abc Starts at character 3
' Abc Starts at character 6
' Abc Starts at character 9
int counter;
Match m;
CaptureCollection cc;
GroupCollection gc;
// Look for groupings of "Abc".
Regex r = new Regex("(Abc)+");
// Define the string to search.
m = r.Match("XYZAbcAbcAbcXYZAbcAb");
gc = m.Groups;
// Display the number of groups.
Console.WriteLine("Captured groups = " + gc.Count.ToString());
// Loop through each group.
for (int i=0; i < gc.Count; i++)
{
cc = gc[i].Captures;
counter = cc.Count;
// Display the number of captures in this group.
Console.WriteLine("Captures count = " + counter.ToString());
// Loop through each capture in the group.
for (int ii = 0; ii < counter; ii++)
{
// Display the capture and its position.
Console.WriteLine(cc[ii] + " Starts at character " +
cc[ii].Index);
}
}
}
// The example displays the following output:
// Captured groups = 2
// Captures count = 1
// AbcAbcAbc Starts at character 3
// Captures count = 3
// Abc Starts at character 3
// Abc Starts at character 6
// Abc Starts at character 9
回到頁首
個別擷取
Capture 類別包含單一子運算式 (Subexpression) 所擷取的結果。 Capture.Value 屬性包含符合的文字,而 Capture.Index 屬性表示符合子字串在輸入字串中以零為起始的開始位置。
下列範例會針對選取城市的溫度剖析輸入字串。 逗號 (",") 是用來分隔城市及其溫度,而分號 (";") 是用來分隔每個城市的資料。 整個輸入字串代表單一相符項目。 在用來剖析字串的規則運算式模式 ((\w+(\s\w+)*),(\d+);)+ 中,城市名稱會指派給第二個擷取群組,而溫度則指派給第四個擷取群組。
Imports System.Text.RegularExpressions
Module Example
Public Sub Main()
Dim input As String = "Miami,78;Chicago,62;New York,67;San Francisco,59;Seattle,58;"
Dim pattern As String = "((\w+(\s\w+)*),(\d+);)+"
Dim match As Match = Regex.Match(input, pattern)
If match.Success Then
Console.WriteLine("Current temperatures:")
For ctr As Integer = 0 To match.Groups(2).Captures.Count - 1
Console.WriteLine("{0,-20} {1,3}", match.Groups(2).Captures(ctr).Value, _
match.Groups(4).Captures(ctr).Value)
Next
End If
End Sub
End Module
' The example displays the following output:
' Current temperatures:
' Miami 78
' Chicago 62
' New York 67
' San Francisco 59
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string input = "Miami,78;Chicago,62;New York,67;San Francisco,59;Seattle,58;";
string pattern = @"((\w+(\s\w+)*),(\d+);)+";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
Console.WriteLine("Current temperatures:");
for (int ctr = 0; ctr < match.Groups[2].Captures.Count; ctr++)
Console.WriteLine("{0,-20} {1,3}", match.Groups[2].Captures[ctr].Value,
match.Groups[4].Captures[ctr].Value);
}
}
}
// The example displays the following output:
// Current temperatures:
// Miami 78
// Chicago 62
// New York 67
// San Francisco 59
此規則運算式的定義方式如下表所示。
模式 |
說明 |
---|---|
\w+ |
比對一個或多個文字字元。 |
(\s\w+)* |
比對零個以上出現的下列模式:空白字元後面接著一個或多個文字字元。 這個模式會比對多字城市名稱。 這是第三個擷取群組。 |
(\w+(\s\w+)*) |
比對一個或多個文字字元後面接著零個以上出現的空白字元和一個或多個文字字元。 這是第二個擷取群組。 |
, |
比對逗號。 |
(\d+) |
比對一個或多個數字。 這是第四個擷取群組。 |
; |
比對分號。 |
((\w+(\s\w+)*),(\d+);)+ |
比對下列模式:單字後面接著任何其他文字,然後接著逗號、一個或多個數字和分號 (一次或多次)。 這是第一個擷取群組。 |
回到頁首
請參閱
參考
System.Text.RegularExpressions